Version Notes
Adds multiple selection features for attribute and price filters in Magento layered navigation.
Download this release
Release Info
Developer | Mana Team |
Extension | Mana_Filters |
Version | 13.10.17.19 |
Comparing to | |
See all releases |
Code changes from version 12.12.21.19 to 13.10.17.19
- app/code/local/Mana/Core/Block/Js.php +18 -2
- app/code/local/Mana/Core/Block/Require.php +21 -0
- app/code/local/Mana/Core/Helper/Data.php +293 -1
- app/code/local/Mana/Core/Helper/Debug.php +37 -0
- app/code/local/Mana/Core/Helper/Files.php +36 -6
- app/code/local/Mana/Core/Helper/Js.php +469 -1
- app/code/local/Mana/Core/Helper/Json.php +22 -0
- app/code/local/Mana/Core/Helper/Layer.php +89 -0
- app/code/local/Mana/Core/Helper/Layout.php +14 -0
- app/code/local/Mana/Core/Helper/Logger.php +110 -0
- app/code/local/Mana/Core/Helper/Mbstring.php +69 -0
- app/code/local/Mana/Core/Helper/PageType.php +24 -0
- app/code/local/Mana/Core/Helper/PageType/Category.php +24 -0
- app/code/local/Mana/Core/Helper/PageType/CmsPage.php +20 -0
- app/code/local/Mana/Core/Helper/PageType/HomePage.php +20 -0
- app/code/local/Mana/Core/Helper/PageType/Search.php +20 -0
- app/code/local/Mana/Core/Helper/Router.php +91 -0
- app/code/local/Mana/Core/Helper/Seo.php +72 -0
- app/code/local/Mana/Core/Helper/UrlTemplate.php +21 -0
- app/code/local/Mana/Core/Helper/Utils.php +118 -0
- app/code/local/Mana/Core/Model/Callback.php +6 -6
- app/code/local/Mana/Core/Model/Closure.php +18 -0
- app/code/local/Mana/Core/Model/Indexer.php +62 -0
- app/code/local/Mana/Core/Model/Observer.php +122 -1
- app/code/local/Mana/Core/Model/Source/Js.php +27 -0
- app/code/local/Mana/Core/Model/Source/YesNoDefault.php +22 -0
- app/code/local/Mana/Core/Resource/Indexer.php +19 -0
- app/code/local/Mana/Core/Rewrite/PageCache/Processor.php +27 -0
- app/code/local/Mana/Core/etc/adminhtml.xml +64 -0
- app/code/local/Mana/Core/etc/config.xml +109 -9
- app/code/local/Mana/Core/etc/system.xml +57 -0
- app/code/local/Mana/Db/Exception/Formula.php +16 -0
- app/code/local/Mana/Db/Exception/Validation.php +15 -2
- app/code/local/Mana/Db/Helper/Config.php +414 -0
- app/code/local/Mana/Db/Helper/Data.php +304 -86
- app/code/local/Mana/Db/Helper/Formula.php +471 -0
- app/code/local/Mana/Db/Helper/Formula/Abstract.php +73 -0
- app/code/local/Mana/Db/Helper/Formula/DependencyFinder.php +100 -0
- app/code/local/Mana/Db/Helper/Formula/Entity.php +45 -0
- app/code/local/Mana/Db/Helper/Formula/Entity/Aggregate.php +87 -0
- app/code/local/Mana/Db/Helper/Formula/Entity/Aggregate/Field.php +60 -0
- app/code/local/Mana/Db/Helper/Formula/Entity/Foreign.php +50 -0
- app/code/local/Mana/Db/Helper/Formula/Entity/Frontend.php +43 -0
- app/code/local/Mana/Db/Helper/Formula/Entity/Normal.php +36 -0
- app/code/local/Mana/Db/Helper/Formula/Evaluator.php +20 -0
- app/code/local/Mana/Db/Helper/Formula/Function.php +28 -0
- app/code/local/Mana/Db/Helper/Formula/Function/Count.php +47 -0
- app/code/local/Mana/Db/Helper/Formula/Function/Glue.php +83 -0
- app/code/local/Mana/Db/Helper/Formula/Function/If.php +51 -0
- app/code/local/Mana/Db/Helper/Formula/Function/Lower.php +30 -0
- app/code/local/Mana/Db/Helper/Formula/Function/Seo.php +33 -0
- app/code/local/Mana/Db/Helper/Formula/Function/SkinUrl.php +32 -0
- app/code/local/Mana/Db/Helper/Formula/Parser.php +379 -0
- app/code/local/Mana/Db/Helper/Formula/Processor.php +63 -0
- app/code/local/Mana/Db/Helper/Formula/Processor/Eav.php +41 -0
- app/code/local/Mana/Db/Helper/Formula/Processor/Entity.php +178 -0
- app/code/local/Mana/Db/Helper/Formula/Processor/System.php +16 -0
- app/code/local/Mana/Db/Helper/Formula/Processor/Table.php +86 -0
- app/code/local/Mana/Db/Helper/Formula/Selector.php +450 -0
- app/code/local/Mana/Db/Model/Entity.php +296 -0
- app/code/local/Mana/Db/Model/Entity/Indexer.php +349 -0
- app/code/local/Mana/Db/Model/Formula/Alias.php +58 -0
- app/code/local/Mana/Db/Model/Formula/Alias/Array.php +104 -0
- app/code/local/Mana/Db/Model/Formula/Alias/Empty.php +68 -0
- app/code/local/Mana/Db/Model/Formula/Alias/Single.php +86 -0
- app/code/local/Mana/Db/Model/Formula/Closure.php +16 -0
- app/code/local/Mana/Db/Model/Formula/Closure/AggregateFieldJoin.php +50 -0
- app/code/local/Mana/Db/Model/Formula/Closure/ForeignJoin.php +28 -0
- app/code/local/Mana/Db/Model/Formula/Closure/ForeignJoinEnd.php +38 -0
- app/code/local/Mana/Db/Model/Formula/Closure/Join.php +44 -0
- app/code/local/Mana/Db/Model/Formula/Context.php +217 -0
- app/code/local/Mana/Db/Model/Formula/Entity.php +53 -0
- app/code/local/Mana/Db/Model/Formula/Expr.php +26 -0
- app/code/local/Mana/Db/Model/Formula/Field.php +37 -0
- app/code/local/Mana/Db/Model/Formula/Node.php +17 -0
- app/code/local/Mana/Db/Model/Formula/Node/Add.php +28 -0
- app/code/local/Mana/Db/Model/Formula/Node/Field.php +21 -0
- app/code/local/Mana/Db/Model/Formula/Node/FormulaExpr.php +17 -0
- app/code/local/Mana/Db/Model/Formula/Node/FunctionCall.php +21 -0
- app/code/local/Mana/Db/Model/Formula/Node/Identifier.php +17 -0
- app/code/local/Mana/Db/Model/Formula/Node/Multiply.php +28 -0
- app/code/local/Mana/Db/Model/Formula/Node/NullValue.php +13 -0
- app/code/local/Mana/Db/Model/Formula/Node/NumberConstant.php +17 -0
- app/code/local/Mana/Db/Model/Formula/Node/StringConstant.php +17 -0
- app/code/local/Mana/Db/Model/Indexer.php +1 -1
- app/code/local/Mana/Db/Model/Observer.php +33 -6
- app/code/local/Mana/Db/Model/Setup.php +84 -0
- app/code/local/Mana/Db/Model/Setup/Abstract.php +33 -0
- app/code/local/Mana/Db/Model/Setup/V13012122.php +478 -0
- app/code/local/Mana/Db/Resource/Edit/Session.php +11 -0
- app/code/local/Mana/Db/Resource/Entity.php +86 -0
- app/code/local/Mana/Db/Resource/Entity/Collection.php +124 -0
- app/code/local/Mana/Db/Resource/Entity/Indexer.php +89 -0
- app/code/local/Mana/Db/Resource/Entity/JsonCollection.php +186 -0
- app/code/local/Mana/Db/Resource/Formula.php +50 -0
- app/code/local/Mana/Db/etc/config.xml +8 -2
- app/code/local/Mana/Db/etc/m_db.xml +44 -0
- app/code/local/Mana/Filters/Block/Filter.php +50 -2
- app/code/local/Mana/Filters/Block/View.php +31 -7
- app/code/local/Mana/Filters/Helper/Data.php +44 -60
- app/code/local/Mana/Filters/Model/Filter/Attribute.php +8 -5
- app/code/local/Mana/Filters/Model/Filter/Category.php +28 -1
- app/code/local/Mana/Filters/Model/Filter/Decimal.php +24 -18
- app/code/local/Mana/Filters/Model/Filter/Price.php +77 -63
- app/code/local/Mana/Filters/Model/Filter2.php +25 -0
- app/code/local/Mana/Filters/Model/Filter2/Store.php +4 -1
- app/code/local/Mana/Filters/Model/Filter2/Value.php +11 -0
- app/code/local/Mana/Filters/Model/Item.php +38 -8
- app/code/local/Mana/Filters/Model/Observer.php +45 -1
- app/code/local/Mana/Filters/Model/Query.php +1 -0
- app/code/local/Mana/Filters/Model/Solr/Attribute.php +42 -8
- app/code/local/Mana/Filters/Model/Solr/Category.php +18 -3
- app/code/local/Mana/Filters/Model/Solr/Decimal.php +8 -6
- app/code/local/Mana/Filters/Model/Solr/Price.php +22 -13
- app/code/local/Mana/Filters/Model/Solr/Reverse/Attribute.php +1 -2
- app/code/local/Mana/Filters/Model/Solr/Reverse/Decimal.php +7 -5
- app/code/local/Mana/Filters/Model/Solr/Reverse/Price.php +11 -9
- app/code/local/Mana/Filters/Resource/Filter/Decimal.php +19 -17
- app/code/local/Mana/Filters/Resource/Filter/Price.php +70 -23
- app/code/local/Mana/Filters/Resource/Filter/Reverse/Decimal.php +18 -16
- app/code/local/Mana/Filters/Resource/Filter/Reverse/Price.php +13 -8
- app/code/local/Mana/Filters/Resource/Filter2.php +13 -0
- app/code/local/Mana/Filters/Resource/Filter2/Store.php +6 -0
- app/code/local/Mana/Filters/Resource/Filter2/Value.php +24 -0
- app/code/local/Mana/Filters/Resource/Filter2/Value/Store.php +5 -1
- app/code/local/Mana/Filters/Resource/Indexer/Source.php +3 -0
- app/code/local/Mana/Filters/Resource/Solr/And/Attribute.php +1 -3
- app/code/local/Mana/Filters/Resource/Solr/Attribute.php +3 -7
- app/code/local/Mana/Filters/Resource/Solr/Collection.php +62 -0
- app/code/local/Mana/Filters/Resource/Solr/Engine.php +24 -0
- app/code/local/Mana/Filters/Resource/Solr/Reverse/Attribute.php +1 -3
- app/code/local/Mana/Filters/etc/config.xml +31 -8
- app/code/local/Mana/Filters/sql/mana_filters_setup/mysql4-upgrade-13.09.11.14-13.09.23.17.php +29 -0
- app/design/adminhtml/default/default/layout/mana_core.xml +5 -2
- app/design/adminhtml/default/default/template/mana/core/js.phtml +9 -0
- app/design/adminhtml/default/default/template/mana/core/require.phtml +14 -0
- app/design/frontend/base/default/layout/mana_core.xml +5 -2
- app/design/frontend/base/default/template/mana/core/js.phtml +9 -0
- app/design/frontend/base/default/template/mana/core/require.phtml +14 -0
- app/design/frontend/base/default/template/mana/filters/cms.phtml +21 -1
- app/design/frontend/base/default/template/mana/filters/items/list.phtml +4 -4
- app/design/frontend/base/default/template/mana/filters/items/list_popup.phtml +10 -8
- app/design/frontend/base/default/template/mana/filters/items/standard.phtml +4 -4
- app/design/frontend/base/default/template/mana/filters/items/standard_popup.phtml +10 -5
- app/design/frontend/base/default/template/mana/filters/state.phtml +1 -0
- app/etc/modules/Mana_Core.xml +6 -0
- app/locale/en_US/Mana_Core.csv +16 -0
- app/locale/en_US/Mana_Db.csv +13 -1
- app/locale/en_US/Mana_Filters.csv +4 -2
- js/jquery/froogaloop.js +290 -0
- js/jquery/froogaloop.min.js +5 -0
- js/jquery/history.js +8 -3
- js/jquery/jquery-1.7.2.min.js +0 -6
- js/jquery/jquery-ui.js +5960 -5485
app/code/local/Mana/Core/Block/Js.php
CHANGED
@@ -12,6 +12,15 @@
|
|
12 |
*
|
13 |
*/
|
14 |
class Mana_Core_Block_Js extends Mage_Core_Block_Template {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* Contains all the translations registered to be passed to client-side scripts
|
17 |
* @var array | null
|
@@ -59,12 +68,19 @@ class Mana_Core_Block_Js extends Mage_Core_Block_Template {
|
|
59 |
}
|
60 |
/**
|
61 |
* Returns all the translations registered to be passed to client-side scripts
|
62 |
-
* @
|
63 |
*/
|
64 |
public function getTranslations() { return $this->_translations; }
|
65 |
/**
|
66 |
* Returns all key-value pair arrays registered to be passed to client-side scripts
|
67 |
-
* @
|
68 |
*/
|
69 |
public function getOptions() { return $this->_options; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
}
|
12 |
*
|
13 |
*/
|
14 |
class Mana_Core_Block_Js extends Mage_Core_Block_Template {
|
15 |
+
protected $_config = array();
|
16 |
+
|
17 |
+
public function setConfig($key, $value) {
|
18 |
+
$this->_config[$key] = $value;
|
19 |
+
return $this;
|
20 |
+
}
|
21 |
+
public function getConfig() {
|
22 |
+
return $this->_config;
|
23 |
+
}
|
24 |
/**
|
25 |
* Contains all the translations registered to be passed to client-side scripts
|
26 |
* @var array | null
|
68 |
}
|
69 |
/**
|
70 |
* Returns all the translations registered to be passed to client-side scripts
|
71 |
+
* @return array | null
|
72 |
*/
|
73 |
public function getTranslations() { return $this->_translations; }
|
74 |
/**
|
75 |
* Returns all key-value pair arrays registered to be passed to client-side scripts
|
76 |
+
* @return array | null
|
77 |
*/
|
78 |
public function getOptions() { return $this->_options; }
|
79 |
+
|
80 |
+
protected function _prepareLayout() {
|
81 |
+
$this
|
82 |
+
->setConfig('url.base', Mage::getUrl('', array('_nosid' => true)))
|
83 |
+
->setConfig('url.secureBase', Mage::getUrl('', array('_secure' => true, '_nosid' => true)));
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
}
|
app/code/local/Mana/Core/Block/Require.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Block_Require extends Mage_Core_Block_Template {
|
13 |
+
protected function _construct() {
|
14 |
+
parent::_construct();
|
15 |
+
$this->setTemplate('mana/core/require.phtml');
|
16 |
+
}
|
17 |
+
|
18 |
+
public function getBaseRequireUrl() {
|
19 |
+
return Mage::getBaseUrl('js').'m-classes';
|
20 |
+
}
|
21 |
+
}
|
app/code/local/Mana/Core/Helper/Data.php
CHANGED
@@ -11,6 +11,8 @@
|
|
11 |
* @author Mana Team
|
12 |
*/
|
13 |
class Mana_Core_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
|
|
|
14 |
/**
|
15 |
* Retrieve config value for store by path. By default uses standard Magento function to query core_config_data
|
16 |
* table and use config.xml for default value. Though this could be replaced by extensions (in later versions).
|
@@ -345,7 +347,7 @@ class Mana_Core_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
345 |
}
|
346 |
return $val;
|
347 |
}
|
348 |
-
|
349 |
return json_encode($this->_forceObjectRecursively($data));
|
350 |
}
|
351 |
protected function _forceObjectRecursively($data) {
|
@@ -403,6 +405,16 @@ class Mana_Core_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
403 |
return $request->getRouteName() . '/' . $request->getControllerName() . '/' . $request->getActionName();
|
404 |
}
|
405 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
public function isMageVersionEqualOrGreater($version) {
|
407 |
$version = explode('.', $version);
|
408 |
$mageVersion = array_values(Mage::getVersionInfo());
|
@@ -517,4 +529,284 @@ class Mana_Core_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
517 |
return null;
|
518 |
}
|
519 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
}
|
11 |
* @author Mana Team
|
12 |
*/
|
13 |
class Mana_Core_Helper_Data extends Mage_Core_Helper_Abstract {
|
14 |
+
protected $_pageTypes;
|
15 |
+
|
16 |
/**
|
17 |
* Retrieve config value for store by path. By default uses standard Magento function to query core_config_data
|
18 |
* table and use config.xml for default value. Though this could be replaced by extensions (in later versions).
|
347 |
}
|
348 |
return $val;
|
349 |
}
|
350 |
+
public function jsonForceObjectAndEncode($data) {
|
351 |
return json_encode($this->_forceObjectRecursively($data));
|
352 |
}
|
353 |
protected function _forceObjectRecursively($data) {
|
405 |
return $request->getRouteName() . '/' . $request->getControllerName() . '/' . $request->getActionName();
|
406 |
}
|
407 |
}
|
408 |
+
public function getRouteParams() {
|
409 |
+
$request = Mage::app()->getRequest();
|
410 |
+
|
411 |
+
$result = '';
|
412 |
+
foreach ($request->getUserParams() as $key => $value) {
|
413 |
+
$result .= '/'.$key.'/'.$value;
|
414 |
+
}
|
415 |
+
return $result;
|
416 |
+
}
|
417 |
+
|
418 |
public function isMageVersionEqualOrGreater($version) {
|
419 |
$version = explode('.', $version);
|
420 |
$mageVersion = array_values(Mage::getVersionInfo());
|
529 |
return null;
|
530 |
}
|
531 |
}
|
532 |
+
|
533 |
+
public function base64EncodeUrl($url) {
|
534 |
+
return base64_encode(Mage::getSingleton('core/url')->sessionUrlVar($url));
|
535 |
+
}
|
536 |
+
|
537 |
+
public function inAdmin() {
|
538 |
+
return $this->getRequestModule(Mage::app()->getRequest()) ==
|
539 |
+
((string)Mage::getConfig()->getNode('admin/routers/adminhtml/args/frontName'));
|
540 |
+
}
|
541 |
+
|
542 |
+
public function getRequestModule(Zend_Controller_Request_Http $request) {
|
543 |
+
$p = $this->getExplodedPath($request);
|
544 |
+
if ($request->getModuleName()) {
|
545 |
+
$result = $request->getModuleName();
|
546 |
+
}
|
547 |
+
else {
|
548 |
+
$result = $p[0];
|
549 |
+
}
|
550 |
+
|
551 |
+
return $result;
|
552 |
+
}
|
553 |
+
|
554 |
+
public function getRequestController(Zend_Controller_Request_Http $request) {
|
555 |
+
$p = $this->getExplodedPath($request);
|
556 |
+
if ($request->getControllerName()) {
|
557 |
+
$result = $request->getControllerName();
|
558 |
+
}
|
559 |
+
else {
|
560 |
+
$result = $p[1];
|
561 |
+
}
|
562 |
+
|
563 |
+
return $result;
|
564 |
+
}
|
565 |
+
|
566 |
+
public function getRequestAction(Zend_Controller_Request_Http $request) {
|
567 |
+
$p = $this->getExplodedPath($request);
|
568 |
+
if ($request->getActionName()) {
|
569 |
+
$result = $request->getActionName();
|
570 |
+
}
|
571 |
+
else {
|
572 |
+
$result = $p[2];
|
573 |
+
}
|
574 |
+
|
575 |
+
return $result;
|
576 |
+
}
|
577 |
+
|
578 |
+
public function getExplodedPath(Zend_Controller_Request_Http $request) {
|
579 |
+
$defaultPath = array(
|
580 |
+
!empty($defaultPath[0]) ? $defaultPath[0] : '',
|
581 |
+
!empty($defaultPath[1]) ? $defaultPath[1] : 'index',
|
582 |
+
!empty($defaultPath[2]) ? $defaultPath[2] : 'index'
|
583 |
+
);
|
584 |
+
|
585 |
+
$path = trim($request->getPathInfo(), '/');
|
586 |
+
|
587 |
+
if ($path) {
|
588 |
+
$path = explode('/', $path);
|
589 |
+
}
|
590 |
+
else {
|
591 |
+
$path = $defaultPath;
|
592 |
+
}
|
593 |
+
|
594 |
+
return $path;
|
595 |
+
}
|
596 |
+
|
597 |
+
/**
|
598 |
+
* @param Mage_Core_Block_Abstract $block
|
599 |
+
*/
|
600 |
+
public function getBlockAlias($block) {
|
601 |
+
if (($parent = $block->getParentBlock()) && $this->startsWith($block->getNameInLayout(), $parent->getNameInLayout().'.')) {
|
602 |
+
return substr($block->getNameInLayout(), strlen($parent->getNameInLayout() . '.'));
|
603 |
+
}
|
604 |
+
else {
|
605 |
+
return $block->getNameInLayout();
|
606 |
+
}
|
607 |
+
}
|
608 |
+
|
609 |
+
public function indexArray($source, $key) {
|
610 |
+
$result = array();
|
611 |
+
foreach ($source as $value) {
|
612 |
+
$result[$value[$key]] = $value;
|
613 |
+
}
|
614 |
+
|
615 |
+
return $result;
|
616 |
+
}
|
617 |
+
|
618 |
+
protected $_attributes = array();
|
619 |
+
|
620 |
+
public function getAttribute($entityType, $attributeCode, $columns) {
|
621 |
+
/* @var $res Mage_Core_Model_Resource */
|
622 |
+
$res = Mage::getSingleton('core/resource');
|
623 |
+
/* @var $db Varien_Db_Adapter_Pdo_Mysql */
|
624 |
+
$db = $res->getConnection('core_read');
|
625 |
+
|
626 |
+
$key = $entityType . '-' . $attributeCode . '-' . implode('-', $columns);
|
627 |
+
if (!isset($this->_attributes[$key])) {
|
628 |
+
$this->_attributes[$key] = $db->fetchRow($db->select()
|
629 |
+
->from(array('a' => $res->getTableName('eav_attribute')), $columns)
|
630 |
+
->join(array('t' => $res->getTableName('eav_entity_type')), 't.entity_type_id = a.entity_type_id', null)
|
631 |
+
->where('a.attribute_code = ?', $attributeCode)
|
632 |
+
->where('t.entity_type_code = ?', $entityType));
|
633 |
+
}
|
634 |
+
|
635 |
+
return $this->_attributes[$key];
|
636 |
+
}
|
637 |
+
|
638 |
+
public function getAttributeTable($attribute) {
|
639 |
+
return $attribute['backend_table'] ?
|
640 |
+
$attribute['backend_table'] :
|
641 |
+
'catalog_category_entity_' . $attribute['backend_type'];
|
642 |
+
}
|
643 |
+
|
644 |
+
/**
|
645 |
+
* @param Varien_Db_Adapter_Pdo_Mysql $connection
|
646 |
+
* @param $tableName
|
647 |
+
* @param array $fields
|
648 |
+
* @param bool $onDuplicate
|
649 |
+
* @return string
|
650 |
+
*/
|
651 |
+
public function insert($connection, $tableName, $fields = array(), $onDuplicate = true) {
|
652 |
+
$sql = "INSERT INTO `{$tableName}` ";
|
653 |
+
$sql .= "(`" . implode('`,`', array_keys($fields)) . "`) ";
|
654 |
+
$sql .= "VALUES (" . implode(',', $fields) . ") ";
|
655 |
+
|
656 |
+
if ($onDuplicate && $fields) {
|
657 |
+
$sql .= " ON DUPLICATE KEY UPDATE";
|
658 |
+
$updateFields = array();
|
659 |
+
foreach ($fields as $key => $field) {
|
660 |
+
$key = $connection->quoteIdentifier($key);
|
661 |
+
$updateFields[] = "{$key}=VALUES({$key})";
|
662 |
+
}
|
663 |
+
$sql .= " " . implode(', ', $updateFields);
|
664 |
+
}
|
665 |
+
|
666 |
+
return $sql;
|
667 |
+
}
|
668 |
+
|
669 |
+
public function addDotToSuffix($suffix) {
|
670 |
+
if ($suffix && $suffix != '/' && strpos($suffix, '.') !== 0) {
|
671 |
+
$suffix = '.' . $suffix;
|
672 |
+
}
|
673 |
+
|
674 |
+
return $suffix;
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* @param string $helper
|
679 |
+
* @return Mana_Core_Helper_PageType[]
|
680 |
+
*/
|
681 |
+
public function getPageTypes($helper = 'helper') {
|
682 |
+
if (!isset($this->_pageTypes[$helper])) {
|
683 |
+
$result = array();
|
684 |
+
|
685 |
+
foreach ($this->getSortedXmlChildren(Mage::getConfig()->getNode('mana_core'), 'page_types') as $key => $pageTypeXml) {
|
686 |
+
/* @var $pageType Mana_Seo_Helper_PageType */
|
687 |
+
$pageType = Mage::helper((string)$pageTypeXml->$helper);
|
688 |
+
$pageType->setCode($key);
|
689 |
+
$result[$key] = $pageType;
|
690 |
+
}
|
691 |
+
$this->_pageTypes[$helper] = $result;
|
692 |
+
}
|
693 |
+
|
694 |
+
return $this->_pageTypes[$helper];
|
695 |
+
}
|
696 |
+
|
697 |
+
/**
|
698 |
+
* @param string $type
|
699 |
+
* @param string $helper
|
700 |
+
* @return Mana_Core_Helper_PageType
|
701 |
+
*/
|
702 |
+
public function getPageType($type, $helper = 'helper') {
|
703 |
+
$pageTypes = $this->getPageTypes($helper);
|
704 |
+
|
705 |
+
return $pageTypes[$type];
|
706 |
+
}
|
707 |
+
|
708 |
+
public function isManadevLayeredNavigationInstalled() {
|
709 |
+
return $this->isModuleEnabled('Mana_Filters');
|
710 |
+
}
|
711 |
+
|
712 |
+
public function isManadevSeoLayeredNavigationInstalled() {
|
713 |
+
return $this->isModuleEnabled('ManaPro_FilterSeoLinks');
|
714 |
+
}
|
715 |
+
|
716 |
+
public function isManadevAttributePageInstalled() {
|
717 |
+
return $this->isModuleEnabled('Mana_AttributePage');
|
718 |
+
}
|
719 |
+
|
720 |
+
public function isManadevLayeredNavigationTreeInstalled() {
|
721 |
+
return $this->isModuleEnabled('ManaPro_FilterTree');
|
722 |
+
}
|
723 |
+
|
724 |
+
public function isManadevLayeredNavigationColorInstalled()
|
725 |
+
{
|
726 |
+
return $this->isModuleEnabled('ManaPro_FilterColors');
|
727 |
+
}
|
728 |
+
|
729 |
+
public function isEnterpriseUrlRewriteInstalled() {
|
730 |
+
return $this->isModuleEnabled('Enterprise_UrlRewrite');
|
731 |
+
}
|
732 |
+
|
733 |
+
protected $_accentTranslations = array(
|
734 |
+
'à' => 'a',
|
735 |
+
'á' => 'a',
|
736 |
+
'â' => 'a',
|
737 |
+
'ã' => 'a',
|
738 |
+
'ä' => 'a',
|
739 |
+
'ç' => 'c',
|
740 |
+
'è' => 'e',
|
741 |
+
'é' => 'e',
|
742 |
+
'ê' => 'e',
|
743 |
+
'ë' => 'e',
|
744 |
+
'ì' => 'i',
|
745 |
+
'í' => 'i',
|
746 |
+
'î' => 'i',
|
747 |
+
'ï' => 'i',
|
748 |
+
'ñ' => 'n',
|
749 |
+
'ò' => 'o',
|
750 |
+
'ó' => 'o',
|
751 |
+
'ô' => 'o',
|
752 |
+
'õ' => 'o',
|
753 |
+
'ö' => 'o',
|
754 |
+
'ù' => 'u',
|
755 |
+
'ú' => 'u',
|
756 |
+
'û' => 'u',
|
757 |
+
'ü' => 'u',
|
758 |
+
'ý' => 'y',
|
759 |
+
'ÿ' => 'y',
|
760 |
+
'À' => 'A',
|
761 |
+
'Á' => 'A',
|
762 |
+
'Â' => 'A',
|
763 |
+
'Ã' => 'A',
|
764 |
+
'Ä' => 'A',
|
765 |
+
'Ç' => 'C',
|
766 |
+
'È' => 'E',
|
767 |
+
'É' => 'E',
|
768 |
+
'Ê' => 'E',
|
769 |
+
'Ë' => 'E',
|
770 |
+
'Ì' => 'I',
|
771 |
+
'Í' => 'I',
|
772 |
+
'Î' => 'I',
|
773 |
+
'Ï' => 'I',
|
774 |
+
'Ñ' => 'N',
|
775 |
+
'Ò' => 'O',
|
776 |
+
'Ó' => 'O',
|
777 |
+
'Ô' => 'O',
|
778 |
+
'Õ' => 'O',
|
779 |
+
'Ö' => 'O',
|
780 |
+
'Ù' => 'U',
|
781 |
+
'Ú' => 'U',
|
782 |
+
'Û' => 'U',
|
783 |
+
'Ü' => 'U',
|
784 |
+
'Ý' => 'Y',
|
785 |
+
);
|
786 |
+
|
787 |
+
protected $_accentTranslationsOld = array(
|
788 |
+
'from' => 'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ',
|
789 |
+
'to' => 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY'
|
790 |
+
);
|
791 |
+
|
792 |
+
public function unaccent($s) {
|
793 |
+
return strtr($s, $this->_accentTranslations);
|
794 |
+
}
|
795 |
+
|
796 |
+
public function getEmptyBlockHtml($block) {
|
797 |
+
Mage::dispatchEvent('core_block_abstract_to_html_before', array('block' => $block));
|
798 |
+
if (Mage::getStoreConfig('advanced/modules_disable_output/' . $block->getModuleName())) {
|
799 |
+
return '';
|
800 |
+
}
|
801 |
+
|
802 |
+
/**
|
803 |
+
* Use single transport object instance for all blocks
|
804 |
+
*/
|
805 |
+
$transportObject = new Varien_Object;
|
806 |
+
$transportObject->setHtml('');
|
807 |
+
Mage::dispatchEvent('core_block_abstract_to_html_after', array('block' => $block, 'transport' => $transportObject));
|
808 |
+
$html = $transportObject->getHtml();
|
809 |
+
|
810 |
+
return $html;
|
811 |
+
}
|
812 |
}
|
app/code/local/Mana/Core/Helper/Debug.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Debug extends Mage_Core_Helper_Abstract
|
13 |
+
{
|
14 |
+
public function logLayout($method) {
|
15 |
+
$filename = "var/log/layout/" . uniqid() . ".xml";
|
16 |
+
Mage::log("$method layout is dumped to {$filename}\n", Zend_Log::DEBUG, 'layout.log');
|
17 |
+
$filename = BP.'/'.$filename;
|
18 |
+
|
19 |
+
$out = '<?xml version="1.0" encoding="UTF-8"?>'."\n<!--\n";
|
20 |
+
$out .= "Called from: \n $method\n";
|
21 |
+
$out .= "Applied handles: \n";
|
22 |
+
|
23 |
+
/* @var $layout Mage_Core_Model_Layout */
|
24 |
+
$layout = Mage::getSingleton('core/layout');
|
25 |
+
|
26 |
+
foreach ($layout->getUpdate()->getHandles() as $handle) {
|
27 |
+
$out .= " $handle\n";
|
28 |
+
}
|
29 |
+
$out .= "-->\n";
|
30 |
+
|
31 |
+
$out .= $layout->getNode()->asNiceXml('');
|
32 |
+
if (!is_dir(dirname($filename))) {
|
33 |
+
mkdir(dirname($filename), 0777, true);
|
34 |
+
}
|
35 |
+
file_put_contents($filename, $out);
|
36 |
+
}
|
37 |
+
}
|
app/code/local/Mana/Core/Helper/Files.php
CHANGED
@@ -12,15 +12,20 @@
|
|
12 |
*
|
13 |
*/
|
14 |
class Mana_Core_Helper_Files extends Mage_Core_Helper_Abstract {
|
15 |
-
|
|
|
|
|
16 |
$result = $this->getBasePath($type).DS.str_replace('/', DS, $relativeUrl);
|
17 |
if (!is_dir(dirname($result))) {
|
18 |
mkdir(dirname($result), 0777, true);
|
19 |
}
|
20 |
return $noExistanceCheck || file_exists($result) ? $result : false;
|
21 |
}
|
22 |
-
public function getBaseUrl($type) {
|
23 |
-
|
|
|
|
|
|
|
24 |
}
|
25 |
public function getBasePath($type) {
|
26 |
return Mage::getConfig()->getOptions()->getMediaDir().DS.'m-'.str_replace('/', DS, $type);
|
@@ -36,10 +41,10 @@ class Mana_Core_Helper_Files extends Mage_Core_Helper_Abstract {
|
|
36 |
}
|
37 |
return false;
|
38 |
}
|
39 |
-
public function getUrl($relativeUrl, $type) {
|
40 |
if (is_array($type)) {
|
41 |
foreach ($type as $candidate) {
|
42 |
-
if ($url = $this->getUrl($relativeUrl, $candidate)) {
|
43 |
return $url;
|
44 |
}
|
45 |
}
|
@@ -47,7 +52,7 @@ class Mana_Core_Helper_Files extends Mage_Core_Helper_Abstract {
|
|
47 |
}
|
48 |
else {
|
49 |
if ($this->getFilename($relativeUrl, $type)) {
|
50 |
-
return $this->getBaseUrl($type).'/'.str_replace(DS, '/', $relativeUrl);
|
51 |
}
|
52 |
else {
|
53 |
return false;
|
@@ -72,4 +77,29 @@ class Mana_Core_Helper_Files extends Mage_Core_Helper_Abstract {
|
|
72 |
$i++;
|
73 |
}
|
74 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
12 |
*
|
13 |
*/
|
14 |
class Mana_Core_Helper_Files extends Mage_Core_Helper_Abstract {
|
15 |
+
protected $skip = array('.', '..');
|
16 |
+
|
17 |
+
public function getFilename($relativeUrl, $type, $noExistanceCheck = false) {
|
18 |
$result = $this->getBasePath($type).DS.str_replace('/', DS, $relativeUrl);
|
19 |
if (!is_dir(dirname($result))) {
|
20 |
mkdir(dirname($result), 0777, true);
|
21 |
}
|
22 |
return $noExistanceCheck || file_exists($result) ? $result : false;
|
23 |
}
|
24 |
+
public function getBaseUrl($type, $baseUrl = null, $storeId = null) {
|
25 |
+
if (!$baseUrl) {
|
26 |
+
$baseUrl = Mage::app()->getStore($storeId)->getBaseUrl('media');
|
27 |
+
}
|
28 |
+
return $baseUrl.'m-'.str_replace(DS, '/', $type);
|
29 |
}
|
30 |
public function getBasePath($type) {
|
31 |
return Mage::getConfig()->getOptions()->getMediaDir().DS.'m-'.str_replace('/', DS, $type);
|
41 |
}
|
42 |
return false;
|
43 |
}
|
44 |
+
public function getUrl($relativeUrl, $type, $baseUrl = null) {
|
45 |
if (is_array($type)) {
|
46 |
foreach ($type as $candidate) {
|
47 |
+
if ($url = $this->getUrl($relativeUrl, $candidate, $baseUrl)) {
|
48 |
return $url;
|
49 |
}
|
50 |
}
|
52 |
}
|
53 |
else {
|
54 |
if ($this->getFilename($relativeUrl, $type)) {
|
55 |
+
return $this->getBaseUrl($type, $baseUrl).'/'.str_replace(DS, '/', $relativeUrl);
|
56 |
}
|
57 |
else {
|
58 |
return false;
|
77 |
$i++;
|
78 |
}
|
79 |
}
|
80 |
+
|
81 |
+
public function walkRecursively($dir, $callback) {
|
82 |
+
if (file_exists($dir)) {
|
83 |
+
$this->_walkRecursively($dir, $callback);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
protected function _walkRecursively($dir, $callback) {
|
88 |
+
if ($handle = opendir($dir)) {
|
89 |
+
$files = array();
|
90 |
+
while (false !== ($file = readdir($handle))) {
|
91 |
+
$files[] = $file;
|
92 |
+
}
|
93 |
+
closedir($handle);
|
94 |
+
foreach ($files as $file) {
|
95 |
+
if (!in_array($file, $this->skip)) {
|
96 |
+
$filename = $dir . '/' . $file;
|
97 |
+
$isDir = is_dir($filename);
|
98 |
+
if (call_user_func($callback, $dir . '/' . $file, $isDir) && $isDir) {
|
99 |
+
$this->_walkRecursively($filename, $callback);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
105 |
}
|
app/code/local/Mana/Core/Helper/Js.php
CHANGED
@@ -11,7 +11,474 @@
|
|
11 |
*
|
12 |
*/
|
13 |
class Mana_Core_Helper_Js extends Mage_Core_Helper_Abstract {
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
* Makes translations of specified strings to be available in client-side scripts.
|
16 |
* @param array $translations
|
17 |
* @return Mana_Core_Helper_Js
|
@@ -45,4 +512,5 @@ jQuery.options($options);
|
|
45 |
</script>
|
46 |
EOT;
|
47 |
}
|
|
|
48 |
}
|
11 |
*
|
12 |
*/
|
13 |
class Mana_Core_Helper_Js extends Mage_Core_Helper_Abstract {
|
14 |
+
#region Dynamic JS and CSS file inclusion
|
15 |
+
protected $_fileConfig;
|
16 |
+
protected $_moduleIndex = array();
|
17 |
+
protected $_tagNames = array('block', 'reference');
|
18 |
+
protected $_pathKeys = array('full_path', 'minified_path');
|
19 |
+
/**
|
20 |
+
* @param Mage_Core_Controller_Varien_Action $action
|
21 |
+
* @param Mage_Core_Model_Layout $layout
|
22 |
+
*/
|
23 |
+
public function processFiles($action, $layout) {
|
24 |
+
// TODO: refactor phases, find positions, then insert all, then delete all
|
25 |
+
Mana_Core_Profiler::start(__METHOD__);
|
26 |
+
|
27 |
+
$layoutXml = $layout->getNode();
|
28 |
+
$layoutDom = new DOMDocument('1.0');
|
29 |
+
$layoutNode = $layoutDom->importNode(dom_import_simplexml($layoutXml), true);
|
30 |
+
$layoutDom->appendChild($layoutNode);
|
31 |
+
$layoutXPath = new DOMXPath($layoutDom);
|
32 |
+
$layoutModified = false;
|
33 |
+
|
34 |
+
$headBlock = $this->_findHeadBlock($layoutXPath);
|
35 |
+
$prototypeAction = $this->_findPrototypeAction($layoutXPath);
|
36 |
+
|
37 |
+
$insertOnDemand = array();
|
38 |
+
$insertEverywhere = array();
|
39 |
+
$delete = array();
|
40 |
+
|
41 |
+
$onDemandInsertPlace = null;
|
42 |
+
$xpath = '';
|
43 |
+
foreach ($this->_getFileConfig() as $name => $fileConfig) {
|
44 |
+
/* @var $config array */
|
45 |
+
/* @var $options array */
|
46 |
+
extract($fileConfig);
|
47 |
+
|
48 |
+
if ($xpath) {
|
49 |
+
$xpath .= ' | ';
|
50 |
+
}
|
51 |
+
$xpath .= $this->_getActionsXPath($config);
|
52 |
+
|
53 |
+
}
|
54 |
+
foreach ($layoutXPath->query($xpath) as $element) {
|
55 |
+
$onDemandInsertPlace = $element;
|
56 |
+
break;
|
57 |
+
}
|
58 |
+
|
59 |
+
// handle javascript minification, merging and inclusion on all pages
|
60 |
+
foreach ($this->_getFileConfig() as $name => $fileConfig) {
|
61 |
+
/* @var $config array */
|
62 |
+
/* @var $options array */
|
63 |
+
extract($fileConfig);
|
64 |
+
|
65 |
+
if (in_array('skip', $options)) {
|
66 |
+
continue;
|
67 |
+
}
|
68 |
+
|
69 |
+
// find all statically defined actions of including a given script
|
70 |
+
$fileActions = $this->_findDomActions($layoutXPath, $config);
|
71 |
+
|
72 |
+
// prepare layout XML action depending on script parameters
|
73 |
+
$action = $this->_createConfigurableAction($layoutDom, $config, $options);
|
74 |
+
|
75 |
+
// insert script where and if appropriate
|
76 |
+
if (in_array('ondemand', $options)) {
|
77 |
+
if ($fileAction = $this->_getFirstElement($fileActions)) {
|
78 |
+
$insertOnDemand[] = array($action, $onDemandInsertPlace);
|
79 |
+
}
|
80 |
+
$delete[] = $fileActions;
|
81 |
+
}
|
82 |
+
elseif (in_array('everywhere', $options)) {
|
83 |
+
$insertEverywhere[] = $action;
|
84 |
+
foreach (array_reverse($insertOnDemand) as $insertOptions) {
|
85 |
+
list($action, $fileAction) = $insertOptions;
|
86 |
+
array_unshift($insertEverywhere, $action);
|
87 |
+
}
|
88 |
+
$insertOnDemand = array();
|
89 |
+
$delete[] = $fileActions;
|
90 |
+
}
|
91 |
+
elseif (in_array('unload', $options)) {
|
92 |
+
$delete[] = $fileActions;
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
// insert configurable on demand js files
|
97 |
+
foreach ($insertOnDemand as $insertOptions) {
|
98 |
+
list($action, $fileAction) = $insertOptions;
|
99 |
+
/* @var $fileAction DOMElement */
|
100 |
+
|
101 |
+
$fileAction->parentNode->insertBefore($action, $fileAction);
|
102 |
+
$layoutModified = true;
|
103 |
+
}
|
104 |
+
|
105 |
+
// insert configurable global js files
|
106 |
+
if ($prototypeAction) {
|
107 |
+
foreach (array_reverse($insertEverywhere) as $action) {
|
108 |
+
$prototypeAction->parentNode->insertBefore($action, $prototypeAction->nextSibling);
|
109 |
+
$layoutModified = true;
|
110 |
+
}
|
111 |
+
}
|
112 |
+
elseif ($headBlock) {
|
113 |
+
foreach (array_reverse($insertEverywhere) as $action) {
|
114 |
+
$headBlock->insertBefore($action, $headBlock->firstChild);
|
115 |
+
$layoutModified = true;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
// delete js files includes via layout XML instructions
|
120 |
+
foreach ($delete as $fileActions) {
|
121 |
+
foreach ($fileActions as $firstFileAction) {
|
122 |
+
/* @var $firstFileAction DOMElement */
|
123 |
+
$firstFileAction->parentNode->removeChild($firstFileAction);
|
124 |
+
$layoutModified = true;
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
if ($layoutModified) {
|
129 |
+
$layout->loadDom($layoutNode);
|
130 |
+
}
|
131 |
+
Mana_Core_Profiler::stop(__METHOD__);
|
132 |
+
}
|
133 |
+
|
134 |
+
public function pageContains($scriptName) {
|
135 |
+
$config = $this->_getFileConfig();
|
136 |
+
if (isset($config[$scriptName])) {
|
137 |
+
$fileConfig = $config[$scriptName];
|
138 |
+
|
139 |
+
/* @var $config array */
|
140 |
+
/* @var $options array */
|
141 |
+
extract($fileConfig);
|
142 |
+
|
143 |
+
if (in_array('ondemand', $options) || in_array('skip', $options)) {
|
144 |
+
/* @var $layout Mage_Core_Model_Layout */
|
145 |
+
$layout = Mage::getSingleton('core/layout');
|
146 |
+
|
147 |
+
return count($this->_findSimpleXmlActions($layout->getNode(), $config)) > 0;
|
148 |
+
}
|
149 |
+
elseif (in_array('everywhere', $options)) {
|
150 |
+
return true;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
return false;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* @param DOMXPath $layoutXPath
|
158 |
+
* @return DOMElement|null
|
159 |
+
*/
|
160 |
+
protected function _findPrototypeAction($layoutXPath) {
|
161 |
+
return $this->_getFirstElement($layoutXPath->query("//block[@name='head']/action" .
|
162 |
+
"[@method='addJs' and script='prototype/prototype.js']"));
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* @param DOMXPath $layoutXPath
|
167 |
+
* @return DOMElement|null
|
168 |
+
*/
|
169 |
+
protected function _findHeadBlock($layoutXPath) {
|
170 |
+
return $this->_getFirstElement($layoutXPath->query("//block[@name='head']"));
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* @param DOMNodeLIst | DOMNode[] $elements
|
175 |
+
* @return DOMElement | null
|
176 |
+
*/
|
177 |
+
protected function _getFirstElement($elements) {
|
178 |
+
foreach ($elements as $element) {
|
179 |
+
return $element;
|
180 |
+
}
|
181 |
+
return null;
|
182 |
+
}
|
183 |
+
|
184 |
+
protected function _getActionsXPath($config) {
|
185 |
+
$xpath = '';
|
186 |
+
foreach ($this->_tagNames as $tagName) {
|
187 |
+
foreach ($this->_pathKeys as $pathKey) {
|
188 |
+
if (!$config[$pathKey]) {
|
189 |
+
continue;
|
190 |
+
}
|
191 |
+
|
192 |
+
if ($xpath) $xpath .= ' | ';
|
193 |
+
$xpath .= "//{$tagName}[@name='head']/action";
|
194 |
+
if ($config['skinnable']) {
|
195 |
+
$xpath .= "[@method='addItem' and type='skin_js' and script='{$config[$pathKey]}']";
|
196 |
+
}
|
197 |
+
else {
|
198 |
+
$xpath .= "[@method='addJs' and script='{$config[$pathKey]}']";
|
199 |
+
}
|
200 |
+
}
|
201 |
+
}
|
202 |
+
return $xpath;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @param DOMXPath $layoutXPath
|
207 |
+
* @param array $config
|
208 |
+
* @return DOMNode[]
|
209 |
+
*/
|
210 |
+
protected function _findDomActions($layoutXPath, $config) {
|
211 |
+
$xpath = $this->_getActionsXPath($config);
|
212 |
+
$result = array();
|
213 |
+
foreach ($layoutXPath->query($xpath) as $element) {
|
214 |
+
$result[] = $element;
|
215 |
+
}
|
216 |
+
return $result;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* @param SimpleXMLElement $layoutSimpleXml
|
221 |
+
* @param array $config
|
222 |
+
* @return SimpleXMLElement[]
|
223 |
+
*/
|
224 |
+
protected function _findSimpleXmlActions($layoutSimpleXml, $config) {
|
225 |
+
$xpath = $this->_getActionsXPath($config);
|
226 |
+
return $layoutSimpleXml->xpath($xpath);
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @param DOMDocument $layoutDom
|
231 |
+
* @param array $config
|
232 |
+
* @param array $options
|
233 |
+
* @return DOMElement
|
234 |
+
*/
|
235 |
+
protected function _createConfigurableAction($layoutDom, $config, $options) {
|
236 |
+
$pathKey = 'full_path';
|
237 |
+
if (in_array('min', $options) && !empty($config['minified_path'])) {
|
238 |
+
$pathKey = 'minified_path';
|
239 |
+
}
|
240 |
+
$jsXml = $config['skinnable']
|
241 |
+
? '<action method="addItem"><type>skin_js</type><name>' . $config[$pathKey] . '</name><params/></action>'
|
242 |
+
: '<action method="addJs"><script>' . $config[$pathKey] . '</script></action>';
|
243 |
+
return $layoutDom->importNode(dom_import_simplexml(simplexml_load_string($jsXml)), true);
|
244 |
+
}
|
245 |
+
|
246 |
+
protected function _getFileConfig() {
|
247 |
+
if (is_null($this->_fileConfig)) {
|
248 |
+
$this->_fileConfig = array();
|
249 |
+
$jsConfig = Mage::getConfig()->getNode('mana_core/js');
|
250 |
+
if ($jsConfig) {
|
251 |
+
$jsChildren = (array)$jsConfig->children();
|
252 |
+
uasort($jsChildren, array($this, '_compareByModuleAndSortOrder'));
|
253 |
+
foreach ($jsChildren as $name => $config) {
|
254 |
+
$options = Mage::getStoreConfig("mana/js/$name");
|
255 |
+
|
256 |
+
/* @var $config Varien_Simplexml_Element */
|
257 |
+
if (empty($config->full_path) || !$options) {
|
258 |
+
continue;
|
259 |
+
}
|
260 |
+
|
261 |
+
$options = explode('_', $options);
|
262 |
+
|
263 |
+
$config = array_merge(array(
|
264 |
+
'type' => 'extension',
|
265 |
+
'skinnable' => false,
|
266 |
+
'full_path' => '',
|
267 |
+
'minified_path' => '',
|
268 |
+
'sort_order' => 1000000,
|
269 |
+
), $config->asArray());
|
270 |
+
|
271 |
+
$this->_fileConfig[$name] = compact('config', 'options');
|
272 |
+
}
|
273 |
+
}
|
274 |
+
}
|
275 |
+
return $this->_fileConfig;
|
276 |
+
}
|
277 |
+
|
278 |
+
public function getSectionSeparator() {
|
279 |
+
return "\n91b5970cd70e2353d866806f8003c1cd56646961\n";
|
280 |
+
}
|
281 |
+
|
282 |
+
protected function _compareByModuleAndSortOrder($a, $b) {
|
283 |
+
if (($result = $this->_compareByModule($a, $b)) != 0) return $result;
|
284 |
+
return $this->_compareBySortOrder($a, $b);
|
285 |
+
}
|
286 |
+
|
287 |
+
protected function _compareByModule($a, $b) {
|
288 |
+
$aIndex = empty($a['module']) ? 1000000 : $this->_getModuleIndex((string)$a['module']);
|
289 |
+
$bIndex = empty($b['module']) ? 1000000 : $this->_getModuleIndex((string)$b['module']);
|
290 |
+
if ($aIndex < $bIndex) return -1;
|
291 |
+
if ($aIndex > $bIndex) return 1;
|
292 |
+
return 0;
|
293 |
+
}
|
294 |
+
|
295 |
+
protected function _compareBySortOrder($a, $b) {
|
296 |
+
$aIndex = empty($a->sort_order) ? 1000000 : ((int)(string)$a->sort_order);
|
297 |
+
$bIndex = empty($b->sort_order) ? 1000000 : ((int)(string)$b->sort_order);
|
298 |
+
if ($aIndex < $bIndex) return -1;
|
299 |
+
if ($aIndex > $bIndex) return 1;
|
300 |
+
|
301 |
+
return 0;
|
302 |
+
}
|
303 |
+
|
304 |
+
protected function _getModuleIndex($moduleName) {
|
305 |
+
if (!isset($this->_moduleIndex[$moduleName])) {
|
306 |
+
$result = 0;
|
307 |
+
foreach (Mage::getConfig()->getNode('modules')->children() as $name => $module) {
|
308 |
+
if ($name = $moduleName) {
|
309 |
+
break;
|
310 |
+
}
|
311 |
+
$result++;
|
312 |
+
}
|
313 |
+
|
314 |
+
$this->_moduleIndex[$moduleName] = $result;
|
315 |
+
}
|
316 |
+
|
317 |
+
return $this->_moduleIndex[$moduleName];
|
318 |
+
}
|
319 |
+
#endregion
|
320 |
+
#region Client side block markup
|
321 |
+
public function wrapClientSideBlock($contentHtml, $params = false) {
|
322 |
+
$info = $this->parseClientSideBlockInfo($params);
|
323 |
+
|
324 |
+
if ($info['is_enabled'] && !$info['is_self_contained']) {
|
325 |
+
return $info['opening_html'].$contentHtml.$info['closing_html'];
|
326 |
+
}
|
327 |
+
else {
|
328 |
+
return $contentHtml;
|
329 |
+
}
|
330 |
+
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* @param string $blockName
|
335 |
+
* @return string
|
336 |
+
*/
|
337 |
+
public function getClientSideBlockName($blockName) {
|
338 |
+
return str_replace('.', '-', str_replace('_', '-', $blockName));
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* @param bool|array|Mage_Core_Block_Abstract $params
|
343 |
+
* @return array
|
344 |
+
*/
|
345 |
+
public function parseClientSideBlockInfo($params = false) {
|
346 |
+
/* @var $core Mana_Core_Helper_Data */
|
347 |
+
$core = Mage::helper('mana_core');
|
348 |
+
|
349 |
+
if ($params instanceof Mage_Core_Block_Abstract) {
|
350 |
+
$block = $params;
|
351 |
+
$params = $block->getMClientSideBlock();
|
352 |
+
if (is_array($params) && empty($params['id']) && !$block->getIsAnonymous()) {
|
353 |
+
$params['id'] = $this->getClientSideBlockName($block->getNameInLayout());
|
354 |
+
}
|
355 |
+
}
|
356 |
+
|
357 |
+
$is_enabled = false;
|
358 |
+
$is_self_contained = false;
|
359 |
+
$element = 'div';
|
360 |
+
$class = '';
|
361 |
+
$style = '';
|
362 |
+
$attributes = array();
|
363 |
+
$opening_html = $closing_html = $class_html = $style_html = $attribute_html = '';
|
364 |
+
|
365 |
+
if (is_array($params)) {
|
366 |
+
$is_enabled = true;
|
367 |
+
if (!empty($params['self_contained'])) {
|
368 |
+
$is_self_contained = true;
|
369 |
+
unset($params['self_contained']);
|
370 |
+
}
|
371 |
+
|
372 |
+
// decide which element to use
|
373 |
+
if (!empty($params['element'])) {
|
374 |
+
$element = $params['element'];
|
375 |
+
unset($params['element']);
|
376 |
+
}
|
377 |
+
|
378 |
+
// assign client side block a unique identifier if possible
|
379 |
+
$id = '';
|
380 |
+
if (!empty($params['id'])) {
|
381 |
+
$id = $params['id'];
|
382 |
+
unset($params['id']);
|
383 |
+
}
|
384 |
+
$class = $id ? 'mb-' . $id : 'm-block';
|
385 |
+
$style = '';
|
386 |
+
|
387 |
+
// set css properties
|
388 |
+
if (isset($params['class'])) {
|
389 |
+
$class .= " {$params['class']}";
|
390 |
+
unset($params['class']);
|
391 |
+
}
|
392 |
+
foreach ($params as $key => $value) {
|
393 |
+
if ($core->startsWith($key, 'style-')) {
|
394 |
+
$style .= "{$value};";
|
395 |
+
unset($params[$key]);
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
// decide on client side block type
|
400 |
+
if (empty($params['m-block'])) {
|
401 |
+
$type = '';
|
402 |
+
if (!empty($params['type'])) {
|
403 |
+
$type = $params['type'];
|
404 |
+
if (in_array($type, array('Mana/Core/Block', 'Mana/Core/NamedBlock'))) {
|
405 |
+
$type = '';
|
406 |
+
}
|
407 |
+
unset($params['type']);
|
408 |
+
}
|
409 |
+
if ($type) {
|
410 |
+
$params['m-block'] = $type;
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
// render client side block element and its contents
|
415 |
+
$opening_html = '<' . $element;
|
416 |
+
if (isset($params['html'])) {
|
417 |
+
foreach ($params['html'] as $key => $value) {
|
418 |
+
$attributes[$key] = $value;
|
419 |
+
if ($attribute_html) $attribute_html .= ' ';
|
420 |
+
$attribute_html .= "$key=\"$value\"";
|
421 |
+
}
|
422 |
+
unset($params['html']);
|
423 |
+
}
|
424 |
+
foreach ($params as $key => $value) {
|
425 |
+
$attributeKey = 'data-' . str_replace('.', '-', str_replace('_', '-', $key));
|
426 |
+
$attributeValue = str_replace('"', '"', str_replace('<', '<', str_replace('>', '>', $value)));
|
427 |
+
$attributes[$attributeKey] = $attributeValue;
|
428 |
+
|
429 |
+
if ($attribute_html) $attribute_html .= ' ';
|
430 |
+
$attribute_html .= "$attributeKey=\"$attributeValue\"";
|
431 |
+
}
|
432 |
+
if ($attribute_html) {
|
433 |
+
$opening_html .= ' ' . $attribute_html;
|
434 |
+
}
|
435 |
+
|
436 |
+
if ($class) {
|
437 |
+
$class_html = 'class="' . $class . '"';
|
438 |
+
$opening_html .= ' '.$class_html;
|
439 |
+
}
|
440 |
+
if ($style) {
|
441 |
+
$style_html = 'style="' . $style . '"';
|
442 |
+
$opening_html .= ' ' . $style_html;
|
443 |
+
}
|
444 |
+
$opening_html .= '>';
|
445 |
+
$closing_html = '</' . $element . '>';
|
446 |
+
|
447 |
+
}
|
448 |
+
|
449 |
+
return compact('is_enabled', 'is_self_contained', 'element', 'class', 'style', 'attributes',
|
450 |
+
'opening_html', 'closing_html', 'class_html', 'style_html', 'attribute_html');
|
451 |
+
}
|
452 |
+
|
453 |
+
public function setConfig($key, $value) {
|
454 |
+
/* @var $layout Mage_Core_Model_Layout */
|
455 |
+
$layout = Mage::getSingleton(strtolower('Core/Layout'));
|
456 |
+
/* @var $jsBlock Mana_Core_Block_Js */
|
457 |
+
$jsBlock = $layout->getBlock('m_js');
|
458 |
+
|
459 |
+
if ($jsBlock) {
|
460 |
+
$jsBlock->setConfig($key, $value);
|
461 |
+
}
|
462 |
+
|
463 |
+
return $this;
|
464 |
+
}
|
465 |
+
|
466 |
+
public function getConfig() {
|
467 |
+
/* @var $layout Mage_Core_Model_Layout */
|
468 |
+
$layout = Mage::getSingleton(strtolower('Core/Layout'));
|
469 |
+
/* @var $jsBlock Mana_Core_Block_Js */
|
470 |
+
$jsBlock = $layout->getBlock('m_js');
|
471 |
+
|
472 |
+
if ($jsBlock) {
|
473 |
+
return $jsBlock->getConfig();
|
474 |
+
}
|
475 |
+
|
476 |
+
return false;
|
477 |
+
}
|
478 |
+
|
479 |
+
#endregion
|
480 |
+
#region Deprecated API for $.options() and $.__() functions
|
481 |
+
/**
|
482 |
* Makes translations of specified strings to be available in client-side scripts.
|
483 |
* @param array $translations
|
484 |
* @return Mana_Core_Helper_Js
|
512 |
</script>
|
513 |
EOT;
|
514 |
}
|
515 |
+
#endregion
|
516 |
}
|
app/code/local/Mana/Core/Helper/Json.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Json extends Mage_Core_Helper_Abstract {
|
13 |
+
public function encodeAttribute($data) {
|
14 |
+
/* @var $core Mana_Core_Helper_Data */
|
15 |
+
$core = Mage::helper('mana_core');
|
16 |
+
|
17 |
+
$result = $core->jsonForceObjectAndEncode($data);
|
18 |
+
$result = implode("\"", str_replace("\"", "'", explode("'", $result)));
|
19 |
+
$result = $this->escapeHtml($result);
|
20 |
+
return $result;
|
21 |
+
}
|
22 |
+
}
|
app/code/local/Mana/Core/Helper/Layer.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Layer extends Mage_Core_Helper_Abstract {
|
13 |
+
public function useSolrForNavigation() {
|
14 |
+
if (!Mage::helper('core')->isModuleEnabled('Enterprise_Search')) {
|
15 |
+
return false;
|
16 |
+
}
|
17 |
+
/* @var $helper Enterprise_Search_Helper_Data */
|
18 |
+
$helper = Mage::helper('enterprise_search');
|
19 |
+
|
20 |
+
return $helper->getIsEngineAvailableForNavigation();
|
21 |
+
}
|
22 |
+
|
23 |
+
public function useSolrForSearch() {
|
24 |
+
if (!Mage::helper('core')->isModuleEnabled('Enterprise_Search')) {
|
25 |
+
return false;
|
26 |
+
}
|
27 |
+
/* @var $helper Enterprise_Search_Helper_Data */
|
28 |
+
$helper = Mage::helper('enterprise_search');
|
29 |
+
|
30 |
+
return $helper->isThirdPartSearchEngine() && $helper->isActiveEngine();
|
31 |
+
}
|
32 |
+
|
33 |
+
public function useSolr() {
|
34 |
+
switch ($this->getMode()) {
|
35 |
+
case 'category':
|
36 |
+
return $this->useSolrForNavigation();
|
37 |
+
case 'search':
|
38 |
+
return $this->useSolrForSearch();
|
39 |
+
default:
|
40 |
+
throw new Exception('Not implemented');
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @param null $mode
|
46 |
+
* @throws Exception
|
47 |
+
* @return Mage_Catalog_Model_Layer
|
48 |
+
*/
|
49 |
+
public function getLayer($mode = null) {
|
50 |
+
if (!$mode) {
|
51 |
+
$mode = $this->getMode();
|
52 |
+
}
|
53 |
+
switch ($mode) {
|
54 |
+
case 'category':
|
55 |
+
return Mage::getSingleton($this->useSolrForNavigation()
|
56 |
+
? 'enterprise_search/catalog_layer'
|
57 |
+
: 'catalog/layer'
|
58 |
+
);
|
59 |
+
case 'search':
|
60 |
+
return Mage::getSingleton($this->useSolrForSearch()
|
61 |
+
? 'enterprise_search/search_layer'
|
62 |
+
: 'catalogsearch/layer'
|
63 |
+
);
|
64 |
+
default:
|
65 |
+
throw new Exception('Not implemented');
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
protected $_mode;
|
70 |
+
|
71 |
+
public function getMode() {
|
72 |
+
if ($this->_mode) {
|
73 |
+
return $this->_mode;
|
74 |
+
}
|
75 |
+
elseif (in_array(Mage::helper('mana_core')->getRoutePath(), array('catalogsearch/result/index', 'manapro_filterajax/search/index'))) {
|
76 |
+
return 'search';
|
77 |
+
}
|
78 |
+
else {
|
79 |
+
return 'category';
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
public function setMode($mode) {
|
84 |
+
$this->_mode = $mode;
|
85 |
+
|
86 |
+
return $this;
|
87 |
+
}
|
88 |
+
|
89 |
+
}
|
app/code/local/Mana/Core/Helper/Layout.php
CHANGED
@@ -34,4 +34,18 @@ class Mana_Core_Helper_Layout extends Mage_Core_Helper_Abstract {
|
|
34 |
if ($a['sortOrder'] > $b['sortOrder']) return 1;
|
35 |
return 0;
|
36 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
}
|
34 |
if ($a['sortOrder'] > $b['sortOrder']) return 1;
|
35 |
return 0;
|
36 |
}
|
37 |
+
|
38 |
+
public function renderBlock($blockName) {
|
39 |
+
/* @var $layout Mage_Core_Model_Layout */
|
40 |
+
$layout = Mage::getSingleton('core/layout');
|
41 |
+
|
42 |
+
/* @var $url Mage_Core_Model_Url */
|
43 |
+
$url = Mage::getSingleton('core/url');
|
44 |
+
if ($block = $layout->getBlock($blockName)) {
|
45 |
+
return $url->sessionUrlVar($block->toHtml());
|
46 |
+
}
|
47 |
+
else {
|
48 |
+
return '';
|
49 |
+
}
|
50 |
+
}
|
51 |
}
|
app/code/local/Mana/Core/Helper/Logger.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mana_Core_Helper_Logger beginSeoMatch(string $message = null)
|
11 |
+
* @method Mana_Core_Helper_Logger logSeoMatch(string $message = null)
|
12 |
+
* @method Mana_Core_Helper_Logger endSeoMatch(string $message = null)
|
13 |
+
|
14 |
+
* @method Mana_Core_Helper_Logger beginSeoUrl(string $message = null)
|
15 |
+
* @method Mana_Core_Helper_Logger logSeoUrl(string $message = null)
|
16 |
+
* @method Mana_Core_Helper_Logger endSeoUrl(string $message = null)
|
17 |
+
|
18 |
+
* @method Mana_Core_Helper_Logger beginDbIndexerFailure(string $message = null)
|
19 |
+
* @method Mana_Core_Helper_Logger logDbIndexerFailure(string $message = null)
|
20 |
+
* @method Mana_Core_Helper_Logger endDbIndexerFailure(string $message = null)
|
21 |
+
|
22 |
+
* @method Mana_Core_Helper_Logger beginUrlIndexer(string $message = null)
|
23 |
+
* @method Mana_Core_Helper_Logger logUrlIndexer(string $message = null)
|
24 |
+
* @method Mana_Core_Helper_Logger endUrlIndexer(string $message = null)
|
25 |
+
|
26 |
+
* @method Mana_Core_Helper_Logger beginTemp(string $message = null)
|
27 |
+
* @method Mana_Core_Helper_Logger logTemp(string $message = null)
|
28 |
+
* @method Mana_Core_Helper_Logger endTemp(string $message = null)
|
29 |
+
*/
|
30 |
+
class Mana_Core_Helper_Logger extends Mage_Core_Helper_Abstract {
|
31 |
+
const INDENT_WIDTH = 4;
|
32 |
+
protected $_isEnabled = array(
|
33 |
+
'all' => false,
|
34 |
+
'seo_match' => false,
|
35 |
+
'seo_url' => false,
|
36 |
+
'db_indexer_failure' => false,
|
37 |
+
'url_indexer' => false,
|
38 |
+
'temp' => true,
|
39 |
+
);
|
40 |
+
protected $_indent = array('all' => 0);
|
41 |
+
|
42 |
+
public function __call($method, $args) {
|
43 |
+
/* @var $core Mana_Core_Helper_Data */
|
44 |
+
$core = Mage::helper('mana_core');
|
45 |
+
if ($core->startsWith($method, 'log')) {
|
46 |
+
$key = $this->_underscore(substr($method, 3));
|
47 |
+
if ($this->_isEnabled[$key]) {
|
48 |
+
if (!isset($this->_indent[$key])) {
|
49 |
+
$this->_indent[$key] = 0;
|
50 |
+
}
|
51 |
+
if (!empty($args[0])) {
|
52 |
+
Mage::log(str_repeat(' ', $this->_indent[$key]) . $args[0], Zend_Log::DEBUG, "m_$key.log");
|
53 |
+
}
|
54 |
+
if ($key != 'all') {
|
55 |
+
if (!empty($args[0])) {
|
56 |
+
Mage::log(str_repeat(' ', $this->_indent['all']) . $args[0], Zend_Log::DEBUG, "m_all.log");
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
return $this;
|
62 |
+
}
|
63 |
+
elseif ($core->startsWith($method, 'begin')) {
|
64 |
+
$key = $this->_underscore(substr($method, 5));
|
65 |
+
if ($this->_isEnabled[$key]) {
|
66 |
+
if (!isset($this->_indent[$key])) {
|
67 |
+
$this->_indent[$key] = 0;
|
68 |
+
}
|
69 |
+
if (!empty($args[0])) {
|
70 |
+
Mage::log(str_repeat(' ', $this->_indent[$key]). $args[0], Zend_Log::DEBUG, "m_$key.log");
|
71 |
+
}
|
72 |
+
$this->_indent[$key] += self::INDENT_WIDTH;
|
73 |
+
if ($key != 'all') {
|
74 |
+
if (!empty($args[0])) {
|
75 |
+
Mage::log(str_repeat(' ', $this->_indent['all']) . $args[0], Zend_Log::DEBUG, "m_all.log");
|
76 |
+
}
|
77 |
+
$this->_indent['all'] += self::INDENT_WIDTH;
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
return $this;
|
82 |
+
}
|
83 |
+
elseif ($core->startsWith($method, 'end')) {
|
84 |
+
$key = $this->_underscore(substr($method, 3));
|
85 |
+
if ($this->_isEnabled[$key]) {
|
86 |
+
if (!isset($this->_indent[$key])) {
|
87 |
+
$this->_indent[$key] = 0;
|
88 |
+
}
|
89 |
+
$this->_indent[$key] -= self::INDENT_WIDTH;
|
90 |
+
if (!empty($args[0])) {
|
91 |
+
Mage::log(str_repeat(' ', $this->_indent[$key]) . $args[0], Zend_Log::DEBUG, "m_$key.log");
|
92 |
+
}
|
93 |
+
if ($key != 'all') {
|
94 |
+
$this->_indent['all'] -= self::INDENT_WIDTH;
|
95 |
+
if (!empty($args[0])) {
|
96 |
+
Mage::log(str_repeat(' ', $this->_indent['all']) . $args[0], Zend_Log::DEBUG, "m_all.log");
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
return $this;
|
102 |
+
}
|
103 |
+
|
104 |
+
throw new Exception("Invalid method " . get_class($this) . "::" . $method . "(" . print_r($args, 1) . ")");
|
105 |
+
}
|
106 |
+
|
107 |
+
protected function _underscore($name) {
|
108 |
+
return strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $name));
|
109 |
+
}
|
110 |
+
}
|
app/code/local/Mana/Core/Helper/Mbstring.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Mbstring extends Mage_Core_Helper_Abstract {
|
13 |
+
protected $_multiByte;
|
14 |
+
public function __construct() {
|
15 |
+
$this->_multiByte = function_exists('mb_strpos');
|
16 |
+
}
|
17 |
+
public function strpos($haystack, $needle, $offset = 0) {
|
18 |
+
if ($this->_multiByte) {
|
19 |
+
return mb_strpos($haystack, $needle, $offset);
|
20 |
+
}
|
21 |
+
else {
|
22 |
+
return strpos($haystack, $needle, $offset);
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
public function strrpos($haystack, $needle, $offset = null) {
|
27 |
+
if ($this->_multiByte) {
|
28 |
+
return is_null($offset) ? mb_strrpos($haystack, $needle) : mb_strrpos($haystack, $needle, $offset);
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
return is_null($offset) ? strrpos($haystack, $needle) : strrpos($haystack, $needle, $offset);
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
public function strlen($haystack) {
|
36 |
+
if ($this->_multiByte) {
|
37 |
+
return mb_strlen($haystack);
|
38 |
+
}
|
39 |
+
else {
|
40 |
+
return strlen($haystack);
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
public function substr($string, $start, $length = null) {
|
45 |
+
if ($this->_multiByte) {
|
46 |
+
return is_null($length) ? mb_substr($string, $start) : mb_substr($string, $start, $length);
|
47 |
+
}
|
48 |
+
else {
|
49 |
+
return is_null($length) ? substr($string, $start) : substr($string, $start, $length);
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
public function endsWith($haystack, $needle) {
|
54 |
+
return ($this->strrpos($haystack, $needle) === $this->strlen($haystack) - $this->strlen($needle));
|
55 |
+
}
|
56 |
+
|
57 |
+
public function startsWith($haystack, $needle) {
|
58 |
+
return ($this->strpos($haystack, $needle) === 0);
|
59 |
+
}
|
60 |
+
|
61 |
+
public function stripos($haystack, $needle, $offset = 0) {
|
62 |
+
if ($this->_multiByte) {
|
63 |
+
return mb_stripos($haystack, $needle, $offset);
|
64 |
+
}
|
65 |
+
else {
|
66 |
+
return stripos($haystack, $needle, $offset);
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
app/code/local/Mana/Core/Helper/PageType.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
abstract class Mana_Core_Helper_PageType extends Mage_Core_Helper_Abstract {
|
9 |
+
protected $_code;
|
10 |
+
|
11 |
+
abstract public function getRoutePath();
|
12 |
+
abstract public function getCurrentSuffix();
|
13 |
+
public function setCode($code) {
|
14 |
+
$this->_code = $code;
|
15 |
+
return $this;
|
16 |
+
}
|
17 |
+
public function getCode() {
|
18 |
+
return $this->_code;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function matchRoute($route) {
|
22 |
+
return $route == $this->getRoutePath();
|
23 |
+
}
|
24 |
+
}
|
app/code/local/Mana/Core/Helper/PageType/Category.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_PageType_Category extends Mana_Core_Helper_PageType {
|
13 |
+
public function getCurrentSuffix() {
|
14 |
+
/* @var $categoryHelper Mage_Catalog_Helper_Category */
|
15 |
+
$categoryHelper = Mage::helper('catalog/category');
|
16 |
+
|
17 |
+
return $categoryHelper->getCategoryUrlSuffix();
|
18 |
+
}
|
19 |
+
|
20 |
+
|
21 |
+
public function getRoutePath() {
|
22 |
+
return 'catalog/category/view';
|
23 |
+
}
|
24 |
+
}
|
app/code/local/Mana/Core/Helper/PageType/CmsPage.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_PageType_CmsPage extends Mana_Core_Helper_PageType {
|
13 |
+
public function getCurrentSuffix() {
|
14 |
+
return Mage::getStoreConfig('mana/seo/cms_page_suffix');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getRoutePath() {
|
18 |
+
return 'cms/page/view';
|
19 |
+
}
|
20 |
+
}
|
app/code/local/Mana/Core/Helper/PageType/HomePage.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_PageType_HomePage extends Mana_Core_Helper_PageType {
|
13 |
+
public function getCurrentSuffix() {
|
14 |
+
return Mage::getStoreConfig('mana/seo/home_page_suffix');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getRoutePath() {
|
18 |
+
return 'cms/index/index';
|
19 |
+
}
|
20 |
+
}
|
app/code/local/Mana/Core/Helper/PageType/Search.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_PageType_Search extends Mana_Core_Helper_PageType {
|
13 |
+
public function getCurrentSuffix() {
|
14 |
+
return Mage::getStoreConfig('mana/seo/search_suffix');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getRoutePath() {
|
18 |
+
return 'catalogsearch/result/index';
|
19 |
+
}
|
20 |
+
}
|
app/code/local/Mana/Core/Helper/Router.php
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Router extends Mage_Core_Helper_Abstract {
|
13 |
+
public function forward($route, $request = null, $params = null, $query = null) {
|
14 |
+
if (is_array($route)) {
|
15 |
+
$this->forward(
|
16 |
+
$route['route'],
|
17 |
+
isset($action['request']) ? $action['request'] : null,
|
18 |
+
isset($action['params']) ? $action['params'] : null,
|
19 |
+
isset($action['query']) ? $action['query'] : null
|
20 |
+
);
|
21 |
+
|
22 |
+
return $this;
|
23 |
+
}
|
24 |
+
if (!$request) {
|
25 |
+
$request = Mage::app()->getRequest();
|
26 |
+
}
|
27 |
+
|
28 |
+
$request->initForward();
|
29 |
+
|
30 |
+
if (!is_null($params)) {
|
31 |
+
$request->setParams($params);
|
32 |
+
}
|
33 |
+
|
34 |
+
list($module, $controller, $action) = explode('/', $route);
|
35 |
+
|
36 |
+
if ($controller != '*') {
|
37 |
+
$request->setControllerName($controller);
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
if ($module != '*') {
|
42 |
+
$request->setModuleName($module);
|
43 |
+
}
|
44 |
+
|
45 |
+
if ($action != '*') {
|
46 |
+
$request->setActionName($action);
|
47 |
+
}
|
48 |
+
|
49 |
+
$request->setDispatched(false);
|
50 |
+
|
51 |
+
if (!is_null($query)) {
|
52 |
+
$_GET = $query;
|
53 |
+
}
|
54 |
+
|
55 |
+
return $this;
|
56 |
+
}
|
57 |
+
|
58 |
+
public function changePath($path, $request = null) {
|
59 |
+
if (!$request) {
|
60 |
+
$request = Mage::app()->getRequest();
|
61 |
+
}
|
62 |
+
|
63 |
+
if ($path === '') {
|
64 |
+
$path = '/';
|
65 |
+
}
|
66 |
+
$request
|
67 |
+
->setPathInfo($path)
|
68 |
+
->setModuleName(null)
|
69 |
+
->setControllerName(null)
|
70 |
+
->setActionName(null)
|
71 |
+
->setDispatched(false);
|
72 |
+
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
public function processWithoutRendering($target, $method) {
|
77 |
+
/* @var $core Mana_Core_Helper_Data */
|
78 |
+
$core = Mage::helper('mana_core');
|
79 |
+
|
80 |
+
Mage::register('m_response_callback', array($target, $method));
|
81 |
+
if ($core->inAdmin() && $target instanceof Mage_Adminhtml_Controller_Action) {
|
82 |
+
/* @var $adminSession Mage_Adminhtml_Model_Session */
|
83 |
+
$adminSession = Mage::getSingleton('adminhtml/session');
|
84 |
+
$adminSession->setDataUsingMethod('is_url_notice', $target->getFlag('', 'check_url_settings'));
|
85 |
+
}
|
86 |
+
Mage::app()->getFrontController()->setDataUsingMethod('no_render', true);
|
87 |
+
|
88 |
+
return $this;
|
89 |
+
}
|
90 |
+
|
91 |
+
}
|
app/code/local/Mana/Core/Helper/Seo.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Seo extends Mage_Core_Helper_Abstract {
|
13 |
+
protected $_urlSymbols;
|
14 |
+
|
15 |
+
protected function _initUrlSymbols() {
|
16 |
+
if (!$this->_urlSymbols) {
|
17 |
+
$this->_urlSymbols = array();
|
18 |
+
$this->_urlSymbols['-'] = Mage::getStoreConfig('mana/seo_symbols/dash');
|
19 |
+
$this->_urlSymbols['/'] = Mage::getStoreConfig('mana/seo_symbols/slash');
|
20 |
+
$this->_urlSymbols['+'] = Mage::getStoreConfig('mana/seo_symbols/plus');
|
21 |
+
$this->_urlSymbols['_'] = Mage::getStoreConfig('mana/seo_symbols/underscore');
|
22 |
+
$this->_urlSymbols["'"] = Mage::getStoreConfig('mana/seo_symbols/quote');
|
23 |
+
$this->_urlSymbols['"'] = Mage::getStoreConfig('mana/seo_symbols/double_quote');
|
24 |
+
$this->_urlSymbols['%'] = Mage::getStoreConfig('mana/seo_symbols/percent');
|
25 |
+
$this->_urlSymbols['#'] = Mage::getStoreConfig('mana/seo_symbols/hash');
|
26 |
+
$this->_urlSymbols['&'] = Mage::getStoreConfig('mana/seo_symbols/ampersand');
|
27 |
+
$this->_urlSymbols[' '] = Mage::getStoreConfig('mana/seo_symbols/space');
|
28 |
+
}
|
29 |
+
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function encode($text) {
|
34 |
+
$this->_initUrlSymbols();
|
35 |
+
foreach ($this->_urlSymbols as $symbol => $urlSymbol) {
|
36 |
+
$text = str_replace($symbol, $urlSymbol, $text);
|
37 |
+
}
|
38 |
+
|
39 |
+
return $text;
|
40 |
+
}
|
41 |
+
|
42 |
+
public function decode($text) {
|
43 |
+
$this->_initUrlSymbols();
|
44 |
+
$result = '';
|
45 |
+
for ($i = 0; $i < mb_strlen($text);) {
|
46 |
+
$found = false;
|
47 |
+
foreach ($this->_urlSymbols as $symbol => $urlSymbol) {
|
48 |
+
if (mb_strpos($text, $urlSymbol, $i) === $i) {
|
49 |
+
$result .= $symbol;
|
50 |
+
$i += mb_strlen($urlSymbol);
|
51 |
+
$found = true;
|
52 |
+
break;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
if (!$found) {
|
56 |
+
$result .= mb_substr($text, $i++, 1);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
return $result;
|
61 |
+
}
|
62 |
+
|
63 |
+
public function select($expr) {
|
64 |
+
$this->_initUrlSymbols();
|
65 |
+
foreach ($this->_urlSymbols as $symbol => $urlSymbol) {
|
66 |
+
$escapedSymbol = str_replace("'", "\\'", $symbol);
|
67 |
+
$expr = "REPLACE($expr, '$escapedSymbol', '$urlSymbol')";
|
68 |
+
}
|
69 |
+
|
70 |
+
return $expr;
|
71 |
+
}
|
72 |
+
}
|
app/code/local/Mana/Core/Helper/UrlTemplate.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_UrlTemplate extends Mage_Core_Helper_Abstract {
|
13 |
+
public function encodeAttribute($data) {
|
14 |
+
if (Mage::app()->getStore()->isAdmin() || Mage::getStoreConfigFlag('mana/ajax/debug')) {
|
15 |
+
return $data;
|
16 |
+
}
|
17 |
+
else {
|
18 |
+
return $this->urlEncode($data);
|
19 |
+
}
|
20 |
+
}
|
21 |
+
}
|
app/code/local/Mana/Core/Helper/Utils.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Helper_Utils extends Mage_Core_Helper_Abstract {
|
13 |
+
/**
|
14 |
+
* @return Mana_Core_Helper_Utils
|
15 |
+
*/
|
16 |
+
public function reindexAll() {
|
17 |
+
/* @var $indexer Mage_Index_Model_Indexer */
|
18 |
+
$indexer = Mage::getSingleton('index/indexer');
|
19 |
+
|
20 |
+
Mage::dispatchEvent('shell_reindex_init_process');
|
21 |
+
foreach ($indexer->getProcessesCollection() as $process) {
|
22 |
+
/* @var $process Mage_Index_Model_Process */
|
23 |
+
$process->reindexEverything();
|
24 |
+
Mage::dispatchEvent($process->getIndexerCode() . '_shell_reindex_after');
|
25 |
+
}
|
26 |
+
Mage::dispatchEvent('shell_reindex_finalize_process');
|
27 |
+
|
28 |
+
return $this;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function reindex($code) {
|
32 |
+
/* @var $indexer Mage_Index_Model_Indexer */
|
33 |
+
$indexer = Mage::getSingleton('index/indexer');
|
34 |
+
|
35 |
+
$indexer->getProcessByCode($code)->reindexAll();
|
36 |
+
|
37 |
+
return $this;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @param string $module
|
42 |
+
* @return Mana_Core_Helper_Utils
|
43 |
+
*/
|
44 |
+
public function disableModuleOutput($module) {
|
45 |
+
/* @var $configData Mage_Core_Model_Config_Data */
|
46 |
+
$configData = Mage::getModel('core/config_data');
|
47 |
+
/* @noinspection PhpUndefinedMethodInspection */
|
48 |
+
$configData
|
49 |
+
->setScope('default')
|
50 |
+
->setScopeId(0)
|
51 |
+
->setPath('advanced/modules_disable_output/'. $module)
|
52 |
+
->setValue(1)
|
53 |
+
->save();
|
54 |
+
|
55 |
+
return $this;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @return Mana_Core_Helper_Utils
|
60 |
+
*/
|
61 |
+
public function clearDiskCache() {
|
62 |
+
/* @var $fileHelper Mana_Core_Helper_Files */
|
63 |
+
$fileHelper = Mage::helper('mana_core/files');
|
64 |
+
$fileHelper->walkRecursively(Mage::getBaseDir('cache'), array($this, '_clearDiskCacheEntry'));
|
65 |
+
|
66 |
+
return $this;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function _clearDiskCacheEntry($filename, $isDir) {
|
70 |
+
if (!$isDir) {
|
71 |
+
unlink($filename);
|
72 |
+
}
|
73 |
+
|
74 |
+
return true;
|
75 |
+
}
|
76 |
+
|
77 |
+
public function setStoreConfig($path, $value, $scope = 'default', $scopeId = 0) {
|
78 |
+
/* @var $res Mage_Core_Model_Resource */
|
79 |
+
$res = Mage::getSingleton('core/resource');
|
80 |
+
|
81 |
+
/* @var $db Varien_Db_Adapter_Pdo_Mysql */
|
82 |
+
$db = $res->getConnection('write');
|
83 |
+
|
84 |
+
/* @var $core Mana_Core_Helper_Data */
|
85 |
+
$core = Mage::helper('mana_core');
|
86 |
+
|
87 |
+
$db->query($core->insert($db, $res->getTableName('core/config_data'), array(
|
88 |
+
'scope' => "'$scope'",
|
89 |
+
'scope_id' => $scopeId,
|
90 |
+
'path' => "'$path'",
|
91 |
+
'value' => "'$value'",
|
92 |
+
)));
|
93 |
+
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function getStoreConfig($path) {
|
98 |
+
$scope = 'default';
|
99 |
+
$scopeId = 0;
|
100 |
+
|
101 |
+
/* @var $collection Mage_Core_Model_Mysql4_Config_Data_Collection */
|
102 |
+
$collection = Mage::getModel('core/config_data')->getCollection();
|
103 |
+
|
104 |
+
$collection->getSelect()
|
105 |
+
->where('scope=?', $scope)
|
106 |
+
->where('scope_id=?', $scopeId)
|
107 |
+
->where('path=?', $path);
|
108 |
+
|
109 |
+
/** @noinspection PhpUnusedLocalVariableInspection */
|
110 |
+
foreach ($collection as $result) {
|
111 |
+
/* @noinspection PhpUndefinedMethodInspection */
|
112 |
+
return $result->getValue();
|
113 |
+
}
|
114 |
+
|
115 |
+
return (string)Mage::getConfig()->getNode('default/'.$path);
|
116 |
+
}
|
117 |
+
|
118 |
+
}
|
app/code/local/Mana/Core/Model/Callback.php
CHANGED
@@ -14,15 +14,15 @@
|
|
14 |
*
|
15 |
*
|
16 |
* @method string | object getTarget()
|
17 |
-
* @method bool hasTarget(
|
18 |
-
* @method Mana_Core_Model_Callback unsTarget(
|
19 |
-
* @method Mana_Core_Model_Callback setTarget(
|
20 |
*
|
21 |
*
|
22 |
* @method string getMethod()
|
23 |
-
* @method bool hasMethod(
|
24 |
-
* @method Mana_Core_Model_Callback unsMethod(
|
25 |
-
* @method Mana_Core_Model_Callback setMethod(
|
26 |
*
|
27 |
*/
|
28 |
class Mana_Core_Model_Callback extends Mana_Core_Model_Object {
|
14 |
*
|
15 |
*
|
16 |
* @method string | object getTarget()
|
17 |
+
* @method bool hasTarget()
|
18 |
+
* @method Mana_Core_Model_Callback unsTarget()
|
19 |
+
* @method Mana_Core_Model_Callback setTarget()
|
20 |
*
|
21 |
*
|
22 |
* @method string getMethod()
|
23 |
+
* @method bool hasMethod()
|
24 |
+
* @method Mana_Core_Model_Callback unsMethod()
|
25 |
+
* @method Mana_Core_Model_Callback setMethod()
|
26 |
*
|
27 |
*/
|
28 |
class Mana_Core_Model_Callback extends Mana_Core_Model_Object {
|
app/code/local/Mana/Core/Model/Closure.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Model_Closure extends Varien_Object {
|
13 |
+
/**
|
14 |
+
* @return mixed
|
15 |
+
*/
|
16 |
+
public function execute() {
|
17 |
+
}
|
18 |
+
}
|
app/code/local/Mana/Core/Model/Indexer.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
abstract class Mana_Core_Model_Indexer extends Mage_Index_Model_Indexer_Abstract {
|
13 |
+
protected $_code;
|
14 |
+
protected $_process;
|
15 |
+
protected $_xml = null;
|
16 |
+
public function getCode() {
|
17 |
+
return $this->_code;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return Mage_Index_Model_Process | bool
|
22 |
+
*/
|
23 |
+
public function getProcess() {
|
24 |
+
if (!$this->_process) {
|
25 |
+
$this->_process = Mage::getModel('index/process')->load($this->getCode(), 'indexer_code');
|
26 |
+
}
|
27 |
+
|
28 |
+
return $this->_process;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @return Varien_Simplexml_Element | bool
|
33 |
+
*/
|
34 |
+
public function getXml() {
|
35 |
+
if (is_null($this->_xml)) {
|
36 |
+
$result = Mage::getConfig()->getXpath("//global/index/indexer/{$this->getProcess()->getIndexerCode()}");
|
37 |
+
|
38 |
+
$this->_xml = count($result) == 1 ? $result[0] : false;
|
39 |
+
}
|
40 |
+
return $this->_xml;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Get Indexer name
|
45 |
+
*
|
46 |
+
* @return string
|
47 |
+
*/
|
48 |
+
public function getName() {
|
49 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
50 |
+
return (string)$this->getXml()->name;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Retrieve Indexer description
|
55 |
+
*
|
56 |
+
* @return string
|
57 |
+
*/
|
58 |
+
public function getDescription() {
|
59 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
60 |
+
return (string)$this->getXml()->description;
|
61 |
+
}
|
62 |
+
}
|
app/code/local/Mana/Core/Model/Observer.php
CHANGED
@@ -58,13 +58,14 @@ class Mana_Core_Model_Observer {
|
|
58 |
/* @var $layout Mage_Core_Model_Layout */
|
59 |
$layout = $observer->getEvent()->getLayout();
|
60 |
|
|
|
61 |
if ($node = Mage::getConfig()->getNode('m_block_layout_handle')) {
|
62 |
foreach ($node->children() as $ruleName => $ruleConfig) {
|
63 |
$if = $ruleConfig->if;
|
64 |
$handleName = (string)$ruleConfig->load_handle;
|
65 |
if ($type = (string)$if['type']) {
|
66 |
if ($this->_hasBlockInXml($type, $layout)) {
|
67 |
-
$
|
68 |
}
|
69 |
}
|
70 |
}
|
@@ -91,8 +92,10 @@ class Mana_Core_Model_Observer {
|
|
91 |
/* @var $action Mage_Core_Controller_Varien_Action */ $action = $observer->getEvent()->getAction();
|
92 |
/* @var $layout Mage_Core_Model_Layout */ $layout = $observer->getEvent()->getLayout();
|
93 |
|
|
|
94 |
Mage::helper('mana_core/layout')->prepareDelayedLayoutBlocks();
|
95 |
|
|
|
96 |
if (Mage::getConfig()->getNode('m_blocks')) {
|
97 |
foreach (Mage::getConfig()->getNode('m_blocks')->children() as $name => $config) {
|
98 |
if (in_array($name, $layout->getUpdate()->getHandles())) {
|
@@ -118,6 +121,7 @@ class Mana_Core_Model_Observer {
|
|
118 |
}
|
119 |
}
|
120 |
}
|
|
|
121 |
}
|
122 |
|
123 |
|
@@ -225,5 +229,122 @@ class Mana_Core_Model_Observer {
|
|
225 |
Mage::register('m_page_is_being_rendered', true);
|
226 |
}
|
227 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
}
|
229 |
|
58 |
/* @var $layout Mage_Core_Model_Layout */
|
59 |
$layout = $observer->getEvent()->getLayout();
|
60 |
|
61 |
+
// load javascript and css files if certain blocks are present
|
62 |
if ($node = Mage::getConfig()->getNode('m_block_layout_handle')) {
|
63 |
foreach ($node->children() as $ruleName => $ruleConfig) {
|
64 |
$if = $ruleConfig->if;
|
65 |
$handleName = (string)$ruleConfig->load_handle;
|
66 |
if ($type = (string)$if['type']) {
|
67 |
if ($this->_hasBlockInXml($type, $layout)) {
|
68 |
+
$layout->getUpdate()->fetchPackageLayoutUpdates((string)$handleName);
|
69 |
}
|
70 |
}
|
71 |
}
|
92 |
/* @var $action Mage_Core_Controller_Varien_Action */ $action = $observer->getEvent()->getAction();
|
93 |
/* @var $layout Mage_Core_Model_Layout */ $layout = $observer->getEvent()->getLayout();
|
94 |
|
95 |
+
// additional layout changes initiated by blocks when all their properties and children are already loaded
|
96 |
Mage::helper('mana_core/layout')->prepareDelayedLayoutBlocks();
|
97 |
|
98 |
+
#region Obsolete, currently does nothing as there is no more m_blocks section in config.xml
|
99 |
if (Mage::getConfig()->getNode('m_blocks')) {
|
100 |
foreach (Mage::getConfig()->getNode('m_blocks')->children() as $name => $config) {
|
101 |
if (in_array($name, $layout->getUpdate()->getHandles())) {
|
121 |
}
|
122 |
}
|
123 |
}
|
124 |
+
#endregion
|
125 |
}
|
126 |
|
127 |
|
229 |
Mage::register('m_page_is_being_rendered', true);
|
230 |
}
|
231 |
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* REPLACE THIS WITH DESCRIPTION (handles event "controller_action_layout_generate_blocks_before")
|
235 |
+
* @param Varien_Event_Observer $observer
|
236 |
+
*/
|
237 |
+
public function processJsCssFiles($observer) {
|
238 |
+
/* @var $action Mage_Core_Controller_Varien_Action */
|
239 |
+
$action = $observer->getEvent()->getAction();
|
240 |
+
/* @var $layout Mage_Core_Model_Layout */
|
241 |
+
$layout = $observer->getEvent()->getLayout();
|
242 |
+
|
243 |
+
/* @var $helper Mana_Core_Helper_Js */
|
244 |
+
$helper = Mage::helper('mana_core/js');
|
245 |
+
|
246 |
+
$helper->processFiles($action, $layout);
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* wrap all blocks marked as client side blocks into container elements
|
251 |
+
* (handles event "core_block_abstract_to_html_after")
|
252 |
+
* @param Varien_Event_Observer $observer
|
253 |
+
*/
|
254 |
+
public function addClientSideBlockMarkup($observer) {
|
255 |
+
/* @var $block Mage_Core_Block_Abstract */
|
256 |
+
$block = $observer->getEvent()->getBlock();
|
257 |
+
/* @var $transport Varien_Object */
|
258 |
+
$transport = $observer->getEvent()->getTransport();
|
259 |
+
|
260 |
+
if ($block->getNameInLayout() == 'head' && ($css = $block->getMCss())) {
|
261 |
+
/* @var $files Mana_Core_Helper_Files */
|
262 |
+
$files = Mage::helper(strtolower('Mana_Core/Files'));
|
263 |
+
$html = '';
|
264 |
+
foreach ($css as $relativeUrl) {
|
265 |
+
if ($files->getFilename($relativeUrl, 'css')) {
|
266 |
+
$html .= '<link rel="stylesheet" type="text/css" href="' . $files->getUrl($relativeUrl, 'css') . '" />' . "\n";
|
267 |
+
}
|
268 |
+
}
|
269 |
+
if ($html) {
|
270 |
+
$transport->setHtml($transport->getHtml() . $html);
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
/* @var $js Mana_Core_Helper_Js */
|
275 |
+
$js = Mage::helper('mana_core/js');
|
276 |
+
$transport->setHtml($js->wrapClientSideBlock($transport->getHtml(), $block));
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* REPLACE THIS WITH DESCRIPTION (handles event "core_block_abstract_to_html_after")
|
281 |
+
* @param Varien_Event_Observer $observer
|
282 |
+
*/
|
283 |
+
public function renderRequireSettings($observer) {
|
284 |
+
/* @var $block Mage_Core_Block_Abstract */
|
285 |
+
$block = $observer->getEvent()->getBlock();
|
286 |
+
/* @var $transport Varien_Object */
|
287 |
+
$transport = $observer->getEvent()->getTransport();
|
288 |
+
|
289 |
+
/* @var $js Mana_Core_Helper_Js */
|
290 |
+
$js = Mage::helper('mana_core/js');
|
291 |
+
|
292 |
+
if ($block->getNameInLayout() == 'head' && $js->pageContains('require')) {
|
293 |
+
$require = $block->getLayout()->createBlock('mana_core/require');
|
294 |
+
$html = $transport->getHtml();
|
295 |
+
$html = $require->toHtml(). $html;
|
296 |
+
|
297 |
+
// replace original content with wrapped one
|
298 |
+
$transport->setHtml($html);
|
299 |
+
}
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* If relevant global flag is raised, renders AJAX content into JSON response instead of typical full-page
|
304 |
+
* HTML response (handles event "controller_front_send_response_before")
|
305 |
+
* @param Varien_Event_Observer $observer
|
306 |
+
*/
|
307 |
+
public function renderCustomResponse($observer) {
|
308 |
+
if ($callback = Mage::registry('m_response_callback')) {
|
309 |
+
call_user_func($callback);
|
310 |
+
}
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* REPLACE THIS WITH DESCRIPTION (handles event "controller_front_init_before")
|
315 |
+
* @param Varien_Event_Observer $observer
|
316 |
+
*/
|
317 |
+
public function registerEarlyRouters($observer) {
|
318 |
+
/* @var $front Mage_Core_Controller_Varien_Front */
|
319 |
+
$front = $observer->getEvent()->getData('front');
|
320 |
+
|
321 |
+
foreach ($this->coreHelper()->getSortedXmlChildren(Mage::getConfig()->getNode('mana_core'), 'routers') as $key => $routerXml) {
|
322 |
+
$class = (string)$routerXml->class;
|
323 |
+
$front->addRouter($key, new $class);
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* REPLACE THIS WITH DESCRIPTION (handles event "controller_front_send_response_before")
|
329 |
+
* @param Varien_Event_Observer $observer
|
330 |
+
*/
|
331 |
+
public function helpSavingInFullPageCache($observer) {
|
332 |
+
if ($queryParameters = Mage::registry('m_temporary_query_parameters')) {
|
333 |
+
foreach (array_keys($queryParameters) as $queryParameter) {
|
334 |
+
if (isset($_GET[$queryParameter])) {
|
335 |
+
unset($_GET[$queryParameter]);
|
336 |
+
}
|
337 |
+
}
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
#region Dependencies
|
342 |
+
/**
|
343 |
+
* @return Mana_Core_Helper_Data
|
344 |
+
*/
|
345 |
+
public function coreHelper() {
|
346 |
+
return Mage::helper('mana_core');
|
347 |
+
}
|
348 |
+
#endregion
|
349 |
}
|
350 |
|
app/code/local/Mana/Core/Model/Source/Js.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Source for options of filter being filterable
|
11 |
+
* @author Mana Team
|
12 |
+
*
|
13 |
+
*/
|
14 |
+
class Mana_Core_Model_Source_Js extends Mana_Core_Model_Source_Abstract {
|
15 |
+
protected function _getAllOptions() {
|
16 |
+
/* @var $t Mana_Core_Helper_Data */
|
17 |
+
$t = Mage::helper(strtolower('Mana_Core'));
|
18 |
+
return array(
|
19 |
+
array('value' => 'min_ondemand', 'label' => $t->__('Load if required, minified version (recommended)')),
|
20 |
+
array('value' => 'min_everywhere', 'label' => $t->__('Load on all pages, minified version')),
|
21 |
+
array('value' => 'full_ondemand', 'label' => $t->__('Load if required, full version with comments')),
|
22 |
+
array('value' => 'full_everywhere', 'label' => $t->__('Load on all pages, full version with comments')),
|
23 |
+
array('value' => 'unload', 'label' => $t->__('Do not load')),
|
24 |
+
array('value' => 'skip', 'label' => $t->__('Take action as defined in theme layout XML files')),
|
25 |
+
);
|
26 |
+
}
|
27 |
+
}
|
app/code/local/Mana/Core/Model/Source/YesNoDefault.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Source for options of filter being filterable
|
11 |
+
* @author Mana Team
|
12 |
+
*
|
13 |
+
*/
|
14 |
+
class Mana_Core_Model_Source_YesNoDefault extends Mana_Core_Model_Source_Abstract {
|
15 |
+
protected function _getAllOptions() {
|
16 |
+
return array(
|
17 |
+
array('value' => '1', 'label' => Mage::helper('core')->__('Yes')),
|
18 |
+
array('value' => '0', 'label' => Mage::helper('core')->__('No')),
|
19 |
+
array('value' => '', 'label' => Mage::helper('core')->__('Use Default')),
|
20 |
+
);
|
21 |
+
}
|
22 |
+
}
|
app/code/local/Mana/Core/Resource/Indexer.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
abstract class Mana_Core_Resource_Indexer extends Mage_Core_Model_Mysql4_Abstract {
|
13 |
+
public function insert($tableName, $fields = array(), $onDuplicate = true) {
|
14 |
+
/* @var $core Mana_Core_Helper_Data */
|
15 |
+
$core = Mage::helper('mana_core');
|
16 |
+
|
17 |
+
return $core->insert($this->_getWriteAdapter(), $tableName, $fields, $onDuplicate);
|
18 |
+
}
|
19 |
+
}
|
app/code/local/Mana/Core/Rewrite/PageCache/Processor.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Core_Rewrite_PageCache_Processor extends Enterprise_PageCache_Model_Processor {
|
13 |
+
protected function _getFullPageUrl() {
|
14 |
+
if ($url = Mage::registry('m_original_request_uri')) {
|
15 |
+
$uri = '';
|
16 |
+
if (isset($_SERVER['HTTP_HOST'])) {
|
17 |
+
$uri = $_SERVER['HTTP_HOST'];
|
18 |
+
} elseif (isset($_SERVER['SERVER_NAME'])) {
|
19 |
+
$uri = $_SERVER['SERVER_NAME'];
|
20 |
+
}
|
21 |
+
if ($uri) {
|
22 |
+
return $uri . $url;
|
23 |
+
}
|
24 |
+
}
|
25 |
+
return parent::_getFullPageUrl();
|
26 |
+
}
|
27 |
+
}
|
app/code/local/Mana/Core/etc/adminhtml.xml
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
@category Mana
|
4 |
+
@package Mana_Core
|
5 |
+
@copyright Copyright (c) http://www.manadev.com
|
6 |
+
@license http://www.manadev.com/license Proprietary License
|
7 |
+
-->
|
8 |
+
<config>
|
9 |
+
<menu>
|
10 |
+
<mana>
|
11 |
+
<title>MANAdev</title>
|
12 |
+
<sort_order>79</sort_order>
|
13 |
+
<children>
|
14 |
+
<system_configuration translate="title" module="mana_core">
|
15 |
+
<title>Global Configuration</title>
|
16 |
+
<sort_order>20000</sort_order>
|
17 |
+
<children>
|
18 |
+
<mana translate="title" module="mana_core">
|
19 |
+
<title>General</title>
|
20 |
+
<action>adminhtml/system_config/edit/section/mana</action>
|
21 |
+
<sort_order>50</sort_order>
|
22 |
+
</mana>
|
23 |
+
</children>
|
24 |
+
</system_configuration>
|
25 |
+
</children>
|
26 |
+
</mana>
|
27 |
+
</menu>
|
28 |
+
<acl>
|
29 |
+
<resources>
|
30 |
+
<admin>
|
31 |
+
<children>
|
32 |
+
<mana translate="title" module="mana_core">
|
33 |
+
<title>Configure Mana Extensions</title>
|
34 |
+
<sort_order>79</sort_order>
|
35 |
+
<children>
|
36 |
+
<system_configuration translate="title" module="mana_core">
|
37 |
+
<title>Global Configuration</title>
|
38 |
+
<sort_order>20000</sort_order>
|
39 |
+
<children>
|
40 |
+
<mana translate="title" module="mana_core">
|
41 |
+
<title>General</title>
|
42 |
+
<sort_order>50</sort_order>
|
43 |
+
</mana>
|
44 |
+
</children>
|
45 |
+
</system_configuration>
|
46 |
+
</children>
|
47 |
+
</mana>
|
48 |
+
<system>
|
49 |
+
<children>
|
50 |
+
<config>
|
51 |
+
<children>
|
52 |
+
<mana translate="title" module="mana_core">
|
53 |
+
<title>MANAdev General Settings</title>
|
54 |
+
<sort_order>50050</sort_order>
|
55 |
+
</mana>
|
56 |
+
</children>
|
57 |
+
</config>
|
58 |
+
</children>
|
59 |
+
</system>
|
60 |
+
</children>
|
61 |
+
</admin>
|
62 |
+
</resources>
|
63 |
+
</acl>
|
64 |
+
</config>
|
app/code/local/Mana/Core/etc/config.xml
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
<Mana_Core>
|
13 |
<!-- This version number identifies version of database tables specific to this extension. It is written to
|
14 |
core_resource table. -->
|
15 |
-
<version>
|
16 |
</Mana_Core>
|
17 |
</modules>
|
18 |
<!-- This section contains module settings which are merged into global configuration during each page load,
|
@@ -27,11 +27,6 @@
|
|
27 |
Mage::helper() calls. -->
|
28 |
<class>Mana_Core_Helper</class>
|
29 |
</mana_core>
|
30 |
-
<catalog>
|
31 |
-
<rewrite>
|
32 |
-
<image>Mana_Core_Helper_Image</image>
|
33 |
-
</rewrite>
|
34 |
-
</catalog>
|
35 |
</helpers>
|
36 |
<!-- BASED ON SNIPPET: Blocks/Block support (config.xml) -->
|
37 |
<!-- This section registers block classes to be accessible from layout XML files (in type="<block type>") or
|
@@ -70,6 +65,11 @@
|
|
70 |
<!-- INSERT HERE: table-entity mappings -->
|
71 |
</entities>
|
72 |
</mana_core_resources>
|
|
|
|
|
|
|
|
|
|
|
73 |
<!-- INSERT HERE: rewrites, ... -->
|
74 |
</models>
|
75 |
<!-- BASED ON SNIPPET: New Models/Event support (config.xml) -->
|
@@ -135,7 +135,65 @@
|
|
135 |
</mana_core>
|
136 |
</observers>
|
137 |
</controller_action_layout_render_before>
|
138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
<!-- BASED ON SNIPPET: Resources/Installation script support (config.xml) -->
|
140 |
<!-- This tells Magento to analyze sql/mana_core_setup directory for install/upgrade scripts.
|
141 |
Installation scripts should be named as 'mysql4-install-<new version>.php'.
|
@@ -174,7 +232,7 @@
|
|
174 |
|
175 |
<!-- INSERT HERE: layout, translate, routers -->
|
176 |
</frontend>
|
177 |
-
|
178 |
<!-- This section enables static visual changes in admin area. -->
|
179 |
<adminhtml>
|
180 |
<!-- BASED ON SNIPPET: Translation support/Adminhtml (config.xml) -->
|
@@ -201,12 +259,54 @@
|
|
201 |
</layout>
|
202 |
<!-- INSERT HERE: layout, translate, routers -->
|
203 |
</adminhtml>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
<!-- INSERT HERE: adminhtml, frontend, ... -->
|
205 |
-
|
206 |
<mana_dev>
|
207 |
<debug>
|
208 |
<jquery_min>1</jquery_min>
|
209 |
</debug>
|
210 |
</mana_dev>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
</default>
|
212 |
</config>
|
12 |
<Mana_Core>
|
13 |
<!-- This version number identifies version of database tables specific to this extension. It is written to
|
14 |
core_resource table. -->
|
15 |
+
<version>13.10.17.19</version>
|
16 |
</Mana_Core>
|
17 |
</modules>
|
18 |
<!-- This section contains module settings which are merged into global configuration during each page load,
|
27 |
Mage::helper() calls. -->
|
28 |
<class>Mana_Core_Helper</class>
|
29 |
</mana_core>
|
|
|
|
|
|
|
|
|
|
|
30 |
</helpers>
|
31 |
<!-- BASED ON SNIPPET: Blocks/Block support (config.xml) -->
|
32 |
<!-- This section registers block classes to be accessible from layout XML files (in type="<block type>") or
|
65 |
<!-- INSERT HERE: table-entity mappings -->
|
66 |
</entities>
|
67 |
</mana_core_resources>
|
68 |
+
<enterprise_pagecache>
|
69 |
+
<rewrite>
|
70 |
+
<processor>Mana_Core_Rewrite_PageCache_Processor</processor>
|
71 |
+
</rewrite>
|
72 |
+
</enterprise_pagecache>
|
73 |
<!-- INSERT HERE: rewrites, ... -->
|
74 |
</models>
|
75 |
<!-- BASED ON SNIPPET: New Models/Event support (config.xml) -->
|
135 |
</mana_core>
|
136 |
</observers>
|
137 |
</controller_action_layout_render_before>
|
138 |
+
<controller_action_layout_generate_blocks_before><!-- this is event name this module listens for -->
|
139 |
+
<observers>
|
140 |
+
<mana_core>
|
141 |
+
<class>mana_core/observer</class>
|
142 |
+
<!-- model name of class containing event handler methods -->
|
143 |
+
<method>processJsCssFiles</method>
|
144 |
+
<!-- event handler method name -->
|
145 |
+
</mana_core>
|
146 |
+
</observers>
|
147 |
+
</controller_action_layout_generate_blocks_before>
|
148 |
+
<core_block_abstract_to_html_after><!-- this is event name this module listens for -->
|
149 |
+
<observers>
|
150 |
+
<mana_core>
|
151 |
+
<class>mana_core/observer</class>
|
152 |
+
<!-- model name of class containing event handler methods -->
|
153 |
+
<method>addClientSideBlockMarkup</method>
|
154 |
+
<!-- event handler method name -->
|
155 |
+
</mana_core>
|
156 |
+
</observers>
|
157 |
+
</core_block_abstract_to_html_after>
|
158 |
+
<core_block_abstract_to_html_after><!-- this is event name this module listens for -->
|
159 |
+
<observers>
|
160 |
+
<mana_core_require>
|
161 |
+
<class>mana_core/observer</class>
|
162 |
+
<!-- model name of class containing event handler methods -->
|
163 |
+
<method>renderRequireSettings</method>
|
164 |
+
<!-- event handler method name -->
|
165 |
+
</mana_core_require>
|
166 |
+
</observers>
|
167 |
+
</core_block_abstract_to_html_after>
|
168 |
+
<controller_front_send_response_before><!-- this is event name this module listens for -->
|
169 |
+
<observers>
|
170 |
+
<mana_core>
|
171 |
+
<class>mana_core/observer</class>
|
172 |
+
<!-- model name of class containing event handler methods -->
|
173 |
+
<method>renderCustomResponse</method>
|
174 |
+
<!-- event handler method name -->
|
175 |
+
</mana_core>
|
176 |
+
</observers>
|
177 |
+
</controller_front_send_response_before>
|
178 |
+
<controller_front_init_before><!-- this is event name this module listens for -->
|
179 |
+
<observers>
|
180 |
+
<mana_core>
|
181 |
+
<class>mana_core/observer</class>
|
182 |
+
<!-- model name of class containing event handler methods -->
|
183 |
+
<method>registerEarlyRouters</method>
|
184 |
+
<!-- event handler method name -->
|
185 |
+
</mana_core>
|
186 |
+
</observers>
|
187 |
+
</controller_front_init_before>
|
188 |
+
<controller_front_send_response_before>
|
189 |
+
<observers>
|
190 |
+
<enterprise_pagecache>
|
191 |
+
<class>mana_core/observer</class>
|
192 |
+
<method>helpSavingInFullPageCache</method>
|
193 |
+
</enterprise_pagecache>
|
194 |
+
</observers>
|
195 |
+
</controller_front_send_response_before>
|
196 |
+
</events>
|
197 |
<!-- BASED ON SNIPPET: Resources/Installation script support (config.xml) -->
|
198 |
<!-- This tells Magento to analyze sql/mana_core_setup directory for install/upgrade scripts.
|
199 |
Installation scripts should be named as 'mysql4-install-<new version>.php'.
|
232 |
|
233 |
<!-- INSERT HERE: layout, translate, routers -->
|
234 |
</frontend>
|
235 |
+
<!-- BASED ON SNIPPET: Static Visuals/Adminhtml section (config.xml) -->
|
236 |
<!-- This section enables static visual changes in admin area. -->
|
237 |
<adminhtml>
|
238 |
<!-- BASED ON SNIPPET: Translation support/Adminhtml (config.xml) -->
|
259 |
</layout>
|
260 |
<!-- INSERT HERE: layout, translate, routers -->
|
261 |
</adminhtml>
|
262 |
+
<mana_core>
|
263 |
+
<js>
|
264 |
+
<!--<require module="mana_core">
|
265 |
+
<type>library</type>
|
266 |
+
<skinnable>0</skinnable>
|
267 |
+
<full_path>jquery/require.js</full_path>
|
268 |
+
<minified_path>jquery/require.min.js</minified_path>
|
269 |
+
<sort_order>50</sort_order>
|
270 |
+
</require>-->
|
271 |
+
<jquery module="mana_core">
|
272 |
+
<type>library</type>
|
273 |
+
<skinnable>0</skinnable>
|
274 |
+
<full_path>jquery/jquery.js</full_path>
|
275 |
+
<minified_path>jquery/jquery.min.js</minified_path>
|
276 |
+
<sort_order>100</sort_order>
|
277 |
+
</jquery>
|
278 |
+
</js>
|
279 |
+
<page_types>
|
280 |
+
<category><helper>mana_core/pageType_category</helper></category>
|
281 |
+
<cms_page><helper>mana_core/pageType_cmsPage</helper></cms_page>
|
282 |
+
<home_page><helper>mana_core/pageType_homePage</helper></home_page>
|
283 |
+
<search><helper>mana_core/pageType_search</helper></search>
|
284 |
+
</page_types>
|
285 |
+
</mana_core>
|
286 |
<!-- INSERT HERE: adminhtml, frontend, ... -->
|
287 |
+
<default>
|
288 |
<mana_dev>
|
289 |
<debug>
|
290 |
<jquery_min>1</jquery_min>
|
291 |
</debug>
|
292 |
</mana_dev>
|
293 |
+
<mana>
|
294 |
+
<js>
|
295 |
+
<!--<require>min_ondemand</require>-->
|
296 |
+
<jquery>min_ondemand</jquery>
|
297 |
+
</js>
|
298 |
+
<seo_symbols>
|
299 |
+
<dash>--to-</dash>
|
300 |
+
<space>-</space>
|
301 |
+
<slash>--per-</slash>
|
302 |
+
<plus>--plus-</plus>
|
303 |
+
<underscore>--uscore-</underscore>
|
304 |
+
<quote>--qt-</quote>
|
305 |
+
<double_quote>--dqt-</double_quote>
|
306 |
+
<hash>--no-</hash>
|
307 |
+
<percent>--percent-</percent>
|
308 |
+
<ampersand>--and-</ampersand>
|
309 |
+
</seo_symbols>
|
310 |
+
</mana>
|
311 |
</default>
|
312 |
</config>
|
app/code/local/Mana/Core/etc/system.xml
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
@category Mana
|
4 |
+
@package Mana_Core
|
5 |
+
@copyright Copyright (c) http://www.manadev.com
|
6 |
+
@license http://www.manadev.com/license Proprietary License
|
7 |
+
-->
|
8 |
+
<config>
|
9 |
+
<tabs>
|
10 |
+
<mana>
|
11 |
+
<label>MANAdev</label>
|
12 |
+
<sort_order>250</sort_order>
|
13 |
+
</mana>
|
14 |
+
</tabs>
|
15 |
+
<sections>
|
16 |
+
<mana translate="label" module="mana_core">
|
17 |
+
<label>General</label>
|
18 |
+
<tab>mana</tab>
|
19 |
+
<frontend_type>text</frontend_type>
|
20 |
+
<sort_order>50</sort_order>
|
21 |
+
<show_in_default>1</show_in_default>
|
22 |
+
<show_in_website>1</show_in_website>
|
23 |
+
<show_in_store>1</show_in_store>
|
24 |
+
<groups>
|
25 |
+
<js translate="label" module="mana_core">
|
26 |
+
<label>JavaScript Libraries</label>
|
27 |
+
<frontend_type>text</frontend_type>
|
28 |
+
<sort_order>10000</sort_order>
|
29 |
+
<show_in_default>1</show_in_default>
|
30 |
+
<show_in_website>1</show_in_website>
|
31 |
+
<show_in_store>1</show_in_store>
|
32 |
+
<fields>
|
33 |
+
<!--<require translate="label">
|
34 |
+
<label>RequireJS (version 2.1.4)</label>
|
35 |
+
<frontend_type>select</frontend_type>
|
36 |
+
<source_model>mana_core/source_js</source_model>
|
37 |
+
<sort_order>50</sort_order>
|
38 |
+
<show_in_default>1</show_in_default>
|
39 |
+
<show_in_website>1</show_in_website>
|
40 |
+
<show_in_store>1</show_in_store>
|
41 |
+
</require>-->
|
42 |
+
<jquery translate="label comment">
|
43 |
+
<label>jQuery (version 1.8.3)</label>
|
44 |
+
<comment>Always runs in jQuery.noConflict() mode (slight modification) to prevent conflicts with Prototype JavaScript library used by Magento.</comment>
|
45 |
+
<frontend_type>select</frontend_type>
|
46 |
+
<source_model>mana_core/source_js</source_model>
|
47 |
+
<sort_order>100</sort_order>
|
48 |
+
<show_in_default>1</show_in_default>
|
49 |
+
<show_in_website>1</show_in_website>
|
50 |
+
<show_in_store>1</show_in_store>
|
51 |
+
</jquery>
|
52 |
+
</fields>
|
53 |
+
</js>
|
54 |
+
</groups>
|
55 |
+
</mana>
|
56 |
+
</sections>
|
57 |
+
</config>
|
app/code/local/Mana/Db/Exception/Formula.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Exception_Formula extends Exception {
|
13 |
+
public function addMessage($message) {
|
14 |
+
$this->message .= $message;
|
15 |
+
}
|
16 |
+
}
|
app/code/local/Mana/Db/Exception/Validation.php
CHANGED
@@ -1,11 +1,24 @@
|
|
1 |
<?php
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
class Mana_Db_Exception_Validation extends Exception {
|
4 |
protected $_errors;
|
5 |
public function __construct($errors) {
|
6 |
$this->_errors = $errors;
|
7 |
}
|
8 |
-
|
|
|
|
|
|
|
|
|
9 |
return $this->_errors;
|
10 |
}
|
11 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
class Mana_Db_Exception_Validation extends Exception {
|
13 |
protected $_errors;
|
14 |
public function __construct($errors) {
|
15 |
$this->_errors = $errors;
|
16 |
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
public function getErrors() {
|
22 |
return $this->_errors;
|
23 |
}
|
24 |
}
|
app/code/local/Mana/Db/Helper/Config.php
ADDED
@@ -0,0 +1,414 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Config extends Mage_Core_Helper_Abstract {
|
13 |
+
const ROLE_PRIMARY_KEY = 'primary_key';
|
14 |
+
const ROLE_DEFAULT_VALUE = 'default_value';
|
15 |
+
const ROLE_STORE_SPECIFICS = 'store_specifics';
|
16 |
+
const ROLE_GRID_EDITING = 'grid_editing';
|
17 |
+
const ROLE_FLAT = 'flat';
|
18 |
+
|
19 |
+
const MODULE_LEVEL = 0;
|
20 |
+
const ENTITY_LEVEL = 1;
|
21 |
+
const SCOPE_LEVEL = 2;
|
22 |
+
const FIELD_LEVEL = 3;
|
23 |
+
|
24 |
+
protected $_xml;
|
25 |
+
protected $_scopeXml = array();
|
26 |
+
protected $_configLevels = array(
|
27 |
+
self::MODULE_LEVEL => 'module',
|
28 |
+
self::ENTITY_LEVEL => 'entity',
|
29 |
+
self::SCOPE_LEVEL => 'scope',
|
30 |
+
self::FIELD_LEVEL => 'field'
|
31 |
+
);
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param string $setupVersion
|
35 |
+
* @return Mana_Db_Model_Setup_Abstract
|
36 |
+
* @throws Exception
|
37 |
+
*/
|
38 |
+
public function getSetup($setupVersion) {
|
39 |
+
// $setupVersion = $this->getXml()->getNode("modules/{$moduleName}/scripts/v{$version}");
|
40 |
+
// if (empty($setupVersion->installer)) {
|
41 |
+
// throw new Exception($this->__("Setup version not defined for module '%s' upgrade script %s",
|
42 |
+
// $moduleName, $version));
|
43 |
+
// }
|
44 |
+
|
45 |
+
$setupVersion = 'mana_db/setup_v' . str_replace('.', '', $setupVersion);
|
46 |
+
if (!($setupVersion = Mage::getModel($setupVersion))) {
|
47 |
+
throw new Exception($this->__("Setup version %s not found", $setupVersion));
|
48 |
+
}
|
49 |
+
|
50 |
+
return $setupVersion;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Load XML config from m_db.xml files and caches it
|
55 |
+
*
|
56 |
+
* @return Varien_Simplexml_Config
|
57 |
+
*/
|
58 |
+
public function getXml() {
|
59 |
+
if (!$this->_xml) {
|
60 |
+
$cachedXml = Mage::app()->loadCache('m_db_config');
|
61 |
+
if ($cachedXml) {
|
62 |
+
$this->_xml = new Varien_Simplexml_Config($cachedXml);
|
63 |
+
}
|
64 |
+
else {
|
65 |
+
$config = new Varien_Simplexml_Config();
|
66 |
+
$config->loadString('<?xml version="1.0"?><config></config>');
|
67 |
+
Mage::getConfig()->loadModulesConfiguration('m_db.xml', $config);
|
68 |
+
$this->_xml = $config;
|
69 |
+
$this->_prepareXml();
|
70 |
+
if (Mage::app()->useCache('config')) {
|
71 |
+
Mage::app()->saveCache($config->getXmlString(), 'm_db_config', array(Mage_Core_Model_Config::CACHE_TAG));
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
return $this->_xml;
|
77 |
+
}
|
78 |
+
|
79 |
+
protected function _prepareXml() {
|
80 |
+
$this->iterate(array(
|
81 |
+
'module' => array($this, '_prepareModuleXml'),
|
82 |
+
'entity' => array($this, '_prepareEntityXml'),
|
83 |
+
'scope' => array($this, '_prepareScopeXml'),
|
84 |
+
'field' => array($this, '_prepareFieldXml'),
|
85 |
+
));
|
86 |
+
|
87 |
+
$this->iterate(array('module' => array($this, '_prepareCustom')));
|
88 |
+
|
89 |
+
$this->iterate(array(
|
90 |
+
'module' => array($this, '_prepareModuleXml'),
|
91 |
+
'entity' => array($this, '_prepareEntityXml'),
|
92 |
+
'scope' => array($this, '_prepareScopeXml'),
|
93 |
+
'field' => array($this, '_prepareFieldXml'),
|
94 |
+
));
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @param Varien_Object $context
|
99 |
+
* @param Varien_Simplexml_Element $module
|
100 |
+
*/
|
101 |
+
protected function _prepareModuleXml($context, $module) {
|
102 |
+
$name = $module->getName();
|
103 |
+
if (!isset($module['module'])) {
|
104 |
+
$module['module'] = $name;
|
105 |
+
}
|
106 |
+
$this->propagateName($module);
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @param Varien_Object $context
|
111 |
+
* @param Varien_Simplexml_Element $module
|
112 |
+
* @param Varien_Simplexml_Element $entity
|
113 |
+
*/
|
114 |
+
protected function _prepareEntityXml($context, $module, $entity) {
|
115 |
+
$this->propagateAttributes($module, $entity, array('module', 'version'));
|
116 |
+
if (empty($entity->scopes)) {
|
117 |
+
$entity->scopes->global->name = 'global';
|
118 |
+
}
|
119 |
+
$this->propagateName($entity);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @param Varien_Object $context
|
124 |
+
* @param Varien_Simplexml_Element $module
|
125 |
+
* @param Varien_Simplexml_Element $entity
|
126 |
+
* @param Varien_Simplexml_Element $scope
|
127 |
+
*/
|
128 |
+
protected function _prepareScopeXml($context, $module, $entity, $scope) {
|
129 |
+
$this->propagateAttributes($entity, $scope, array('module', 'version'));
|
130 |
+
foreach ($entity->children() as $child) {
|
131 |
+
if ($child->getName() != 'scopes') {
|
132 |
+
$scope->extendChild($child);
|
133 |
+
}
|
134 |
+
}
|
135 |
+
if (!empty($scope->unique)) {
|
136 |
+
/** @noinspection PhpParamsInspection */
|
137 |
+
$this->propagateAttributes($scope, $scope->unique, array('module', 'version'));
|
138 |
+
foreach ($scope->unique->children() as $index) {
|
139 |
+
/** @noinspection PhpParamsInspection */
|
140 |
+
$this->propagateAttributes($scope->unique, $index, array('module', 'version'));
|
141 |
+
foreach ($index->children() as $column) {
|
142 |
+
$this->propagateAttributes($index, $column, array('module', 'version'));
|
143 |
+
}
|
144 |
+
}
|
145 |
+
}
|
146 |
+
$this->propagateName($scope);
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* @param Varien_Object $context
|
151 |
+
* @param Varien_Simplexml_Element $module
|
152 |
+
* @param Varien_Simplexml_Element $entity
|
153 |
+
* @param Varien_Simplexml_Element $scope
|
154 |
+
* @param Varien_Simplexml_Element $field
|
155 |
+
*/
|
156 |
+
protected function _prepareFieldXml($context, $module, $entity, $scope, $field) {
|
157 |
+
$this->propagateAttributes($scope, $field, array('module', 'version'));
|
158 |
+
$this->propagateName($field);
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @param Varien_Object $context
|
163 |
+
* @param Varien_Simplexml_Element $module
|
164 |
+
*/
|
165 |
+
protected function _prepareCustom($context, $module) {
|
166 |
+
if (!$module->installer_versions) {
|
167 |
+
return;
|
168 |
+
}
|
169 |
+
|
170 |
+
foreach ($module->installer_versions->children() as $moduleVersion => $version) {
|
171 |
+
$version = (string) $version;
|
172 |
+
|
173 |
+
$setupVersion = $this->getSetup((string)$version);
|
174 |
+
$setupVersion
|
175 |
+
->setModuleName((string)$module->name)
|
176 |
+
->setVersion(substr($moduleVersion, 1))
|
177 |
+
->prepare();
|
178 |
+
}
|
179 |
+
}
|
180 |
+
/**
|
181 |
+
* @param Varien_Simplexml_Element $source
|
182 |
+
* @param Varien_Simplexml_Element $target
|
183 |
+
* @param string[] $attributes
|
184 |
+
*/
|
185 |
+
public function propagateAttributes($source, $target, $attributes) {
|
186 |
+
foreach ($attributes as $attribute) {
|
187 |
+
if (!isset($target[$attribute]) && isset($source[$attribute])) {
|
188 |
+
$target[$attribute] = (string)$source[$attribute];
|
189 |
+
}
|
190 |
+
}
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* @param Varien_Simplexml_Element $target
|
195 |
+
*/
|
196 |
+
public function propagateName($target) {
|
197 |
+
$target->name = $target->getName();
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* @param callable[] $callbacks
|
202 |
+
*/
|
203 |
+
public function iterate($callbacks) {
|
204 |
+
$args = array(new Varien_Object());
|
205 |
+
$config = $this->_xml ? $this->_xml->getNode() : $this->getXml()->getNode();
|
206 |
+
$this->_iterateLevel(self::MODULE_LEVEL, $config->modules, $callbacks, $args,
|
207 |
+
array($this, '_iterateEntities'));
|
208 |
+
return $args[0];
|
209 |
+
}
|
210 |
+
|
211 |
+
protected function _iterateLevel ($level, $elements, $callbacks, $args, $deeperLevelIterator = null) {
|
212 |
+
if (!$elements) {
|
213 |
+
return;
|
214 |
+
}
|
215 |
+
$hasCallbacks = false;
|
216 |
+
foreach ($this->_configLevels as $levelIndex =>$levelKey) {
|
217 |
+
if ($levelIndex < $level) {
|
218 |
+
continue;
|
219 |
+
}
|
220 |
+
$intersection = array_intersect(array("{$levelKey}_before", $levelKey, "{$levelKey}_after"),
|
221 |
+
array_keys($callbacks));
|
222 |
+
if (!empty($intersection)) {
|
223 |
+
$hasCallbacks = true;
|
224 |
+
break;
|
225 |
+
}
|
226 |
+
}
|
227 |
+
if (!$hasCallbacks) {
|
228 |
+
return;
|
229 |
+
}
|
230 |
+
|
231 |
+
$callbackKey = $this->_configLevels[$level];
|
232 |
+
foreach ($elements->children() as $config) {
|
233 |
+
$argsToBePassed = array_merge($args, array($config));
|
234 |
+
if (isset($callbacks["{$callbackKey}_before"])) {
|
235 |
+
call_user_func_array($callbacks["{$callbackKey}_before"], $argsToBePassed);
|
236 |
+
}
|
237 |
+
if (isset($callbacks[$callbackKey])) {
|
238 |
+
call_user_func_array($callbacks[$callbackKey], $argsToBePassed);
|
239 |
+
}
|
240 |
+
if ($deeperLevelIterator) {
|
241 |
+
call_user_func($deeperLevelIterator, $config, $callbacks, $argsToBePassed);
|
242 |
+
}
|
243 |
+
if (isset($callbacks["{$callbackKey}_after"])) {
|
244 |
+
call_user_func_array($callbacks["{$callbackKey}_after"], $argsToBePassed);
|
245 |
+
}
|
246 |
+
}
|
247 |
+
}
|
248 |
+
protected function _iterateEntities($config, $callbacks, $args) {
|
249 |
+
$this->_iterateLevel(self::ENTITY_LEVEL, $config->entities, $callbacks, $args,
|
250 |
+
array($this, '_iterateScopes'));
|
251 |
+
}
|
252 |
+
protected function _iterateScopes($config, $callbacks, $args) {
|
253 |
+
$this->_iterateLevel(self::SCOPE_LEVEL, $config->scopes, $callbacks, $args,
|
254 |
+
array($this, '_iterateFields'));
|
255 |
+
}
|
256 |
+
protected function _iterateFields($config, $callbacks, $args) {
|
257 |
+
$this->_iterateLevel(self::FIELD_LEVEL, $config->fields, $callbacks, $args);
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* @param string $entityName
|
262 |
+
* @return Varien_Simplexml_Element | bool
|
263 |
+
*/
|
264 |
+
public function getEntityXml($entityName) {
|
265 |
+
$xml = $this->getXml();
|
266 |
+
$parts = explode('/', $entityName);
|
267 |
+
list($module, $entity) = $parts;
|
268 |
+
$entityXml = $xml->getXpath("//modules/$module/entities/$entity");
|
269 |
+
|
270 |
+
return empty($entityXml) ? false : $entityXml[0];
|
271 |
+
}
|
272 |
+
|
273 |
+
public function getTableXml($entityName) {
|
274 |
+
$xml = $this->getXml();
|
275 |
+
$parts = explode('/', $entityName);
|
276 |
+
list($module, $entity) = $parts;
|
277 |
+
$entityXml = $xml->getXpath("//modules/$module/tables/$entity");
|
278 |
+
|
279 |
+
return empty($entityXml) ? false : $entityXml[0];
|
280 |
+
}
|
281 |
+
|
282 |
+
|
283 |
+
/**
|
284 |
+
* @param string $fullEntityName
|
285 |
+
* @return Varien_Simplexml_Element | bool
|
286 |
+
*/
|
287 |
+
public function getScopeXml($fullEntityName) {
|
288 |
+
if (!isset($this->_scopeXml[$fullEntityName])) {
|
289 |
+
$xml = $this->getXml();
|
290 |
+
$parts = explode('/', $fullEntityName);
|
291 |
+
if (count($parts) > 2) {
|
292 |
+
list($module, $entity, $scope) = $parts;
|
293 |
+
}
|
294 |
+
else {
|
295 |
+
list($module, $entity) = $parts;
|
296 |
+
$scope = 'global';
|
297 |
+
}
|
298 |
+
$scopeXml = $xml->getXpath("//modules/$module/entities/$entity/scopes/$scope");
|
299 |
+
if (empty($scopeXml) && $scope == 'global') {
|
300 |
+
$scopeXml = $xml->getXpath("//modules/$module/entities/$entity");
|
301 |
+
}
|
302 |
+
|
303 |
+
$this->_scopeXml[$fullEntityName] = empty($scopeXml) ? false : $scopeXml[0];
|
304 |
+
}
|
305 |
+
return $this->_scopeXml[$fullEntityName];
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* @param string $entity
|
310 |
+
* @param string $field
|
311 |
+
* @return Varien_Simplexml_Element | bool
|
312 |
+
*/
|
313 |
+
public function getFieldXml($entity, $field) {
|
314 |
+
$scopeXml = $this->getScopeXml($entity);
|
315 |
+
|
316 |
+
$resultXml = $scopeXml->xpath("fields/$field");
|
317 |
+
return empty($resultXml) ? false : $resultXml[0];
|
318 |
+
}
|
319 |
+
|
320 |
+
public function getForeignKey($parentEntity, $childEntity) {
|
321 |
+
/* @var $db Mana_Db_Helper_Data */
|
322 |
+
$db = Mage::helper('mana_db');
|
323 |
+
|
324 |
+
$scopeXml = $this->getScopeXml($childEntity);
|
325 |
+
|
326 |
+
$resultXml = $scopeXml->xpath("fields/*[foreign/entity='$parentEntity' or ".
|
327 |
+
"foreign/entity='{$parentEntity}/global']");
|
328 |
+
if (empty($resultXml)) {
|
329 |
+
return false;
|
330 |
+
}
|
331 |
+
|
332 |
+
/* @var $fieldXml Varien_Simplexml_Element */
|
333 |
+
$fieldXml = $resultXml[0];
|
334 |
+
return $fieldXml->getName();
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* @param string $entity
|
339 |
+
* @return Varien_Simplexml_Element[]
|
340 |
+
*/
|
341 |
+
public function getForeignXmls($entity) {
|
342 |
+
/* @var $db Mana_Db_Helper_Data */
|
343 |
+
$db = Mage::helper('mana_db');
|
344 |
+
|
345 |
+
$scopeXml = $this->getScopeXml($entity);
|
346 |
+
|
347 |
+
return $scopeXml->xpath("fields/*[foreign]");
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* @param string $entity
|
352 |
+
* @return Varien_Simplexml_Element[]
|
353 |
+
*/
|
354 |
+
public function getScopeValidators($entity) {
|
355 |
+
$scopeXml = $this->getScopeXml($entity);
|
356 |
+
return $scopeXml->xpath("validation/*");
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* @param string $entity
|
361 |
+
* @return Varien_Simplexml_Element[]
|
362 |
+
*/
|
363 |
+
public function getScopeFields($entity) {
|
364 |
+
$scopeXml = $this->getScopeXml($entity);
|
365 |
+
|
366 |
+
return $scopeXml->xpath("fields/*");
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* @param string $entity
|
371 |
+
* @param string $field
|
372 |
+
* @return Varien_Simplexml_Element || bool
|
373 |
+
*/
|
374 |
+
public function getScopeField($entity, $field) {
|
375 |
+
$scopeXml = $this->getScopeXml($entity);
|
376 |
+
|
377 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
378 |
+
$result = $scopeXml->fields->$field;
|
379 |
+
return empty($result) ? false : $result;
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* @param string $entity
|
384 |
+
* @param string $field
|
385 |
+
* @return Varien_Simplexml_Element[]
|
386 |
+
*/
|
387 |
+
public function getFieldValidators($entity, $field = null) {
|
388 |
+
$fieldXml = $entity instanceof Varien_Simplexml_Element ? $entity : $this->getFieldXml($entity, $field);
|
389 |
+
|
390 |
+
return $fieldXml->xpath("validation/*");
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* @param string $entity
|
395 |
+
* @return Varien_Simplexml_Element[]
|
396 |
+
*/
|
397 |
+
public function getScopePostValidators($entity) {
|
398 |
+
$scopeXml = $this->getScopeXml($entity);
|
399 |
+
|
400 |
+
return $scopeXml->xpath("post_validation/*");
|
401 |
+
}
|
402 |
+
|
403 |
+
/**
|
404 |
+
* @param string $entity
|
405 |
+
* @param string $field
|
406 |
+
* @return Varien_Simplexml_Element[]
|
407 |
+
*/
|
408 |
+
public function getFieldPostValidators($entity, $field = null) {
|
409 |
+
$fieldXml = $entity instanceof Varien_Simplexml_Element ? $entity : $this->getFieldXml($entity, $field);
|
410 |
+
|
411 |
+
return $fieldXml->xpath("post_validation/*");
|
412 |
+
}
|
413 |
+
|
414 |
+
}
|
app/code/local/Mana/Db/Helper/Data.php
CHANGED
@@ -11,9 +11,36 @@
|
|
11 |
* @author Mana Team
|
12 |
*/
|
13 |
class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
14 |
-
protected $_logQueries =
|
|
|
|
|
15 |
public function getLogQueries() {
|
16 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
}
|
18 |
public function logQuery($action, $query) {
|
19 |
if ($this->getLogQueries()) {
|
@@ -21,7 +48,7 @@ class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
21 |
}
|
22 |
}
|
23 |
public function logAction($action, $object) {
|
24 |
-
if ($this->
|
25 |
Mage::log($action.': '.$object->toJson(), Zend_Log::DEBUG, 'replicate.log');
|
26 |
}
|
27 |
}
|
@@ -47,7 +74,7 @@ class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
47 |
}
|
48 |
public function joinLeft($select, $alias, $table, $condition) {
|
49 |
if (!array_key_exists($alias, $select->getPart(Zend_Db_Select::FROM))) {
|
50 |
-
$select->joinLeft(array($alias => $table), $condition, null);
|
51 |
}
|
52 |
return $select;
|
53 |
}
|
@@ -102,11 +129,17 @@ class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
102 |
$options = array_merge(array(
|
103 |
'db' => Mage::getSingleton('core/resource')->getConnection('core/write'),
|
104 |
'trackKeys' => false,
|
105 |
-
'transaction' =>
|
106 |
'filter' => array(),
|
107 |
-
'batchSize' =>
|
108 |
-
'object' => null,
|
109 |
), $options);
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
if (count($options['filter']) == 0) {
|
111 |
$options['db']->resetDdlCache();
|
112 |
}
|
@@ -136,89 +169,93 @@ class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
136 |
$model = Mage::getResourceSingleton($entityName);
|
137 |
|
138 |
// update existing rows
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
|
|
|
|
166 |
}
|
167 |
-
|
168 |
// insert rows
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
196 |
}
|
197 |
-
|
198 |
// delete rows
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
222 |
if ($options['transaction']) {
|
223 |
$options['db']->commit();
|
224 |
}
|
@@ -327,6 +364,9 @@ class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
327 |
return $a < $b ? -1 : 1;
|
328 |
}
|
329 |
|
|
|
|
|
|
|
330 |
protected $_inEditing = false;
|
331 |
public function getInEditing() {
|
332 |
return $this->_inEditing;
|
@@ -360,4 +400,182 @@ class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
360 |
'deleted' => array(),
|
361 |
);
|
362 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
}
|
11 |
* @author Mana Team
|
12 |
*/
|
13 |
class Mana_Db_Helper_Data extends Mage_Core_Helper_Abstract {
|
14 |
+
protected $_logQueries = false;
|
15 |
+
protected $_resourceSingletons = array();
|
16 |
+
|
17 |
public function getLogQueries() {
|
18 |
+
return Mage::getStoreConfig('mana_db/replicate/log_queries');
|
19 |
+
}
|
20 |
+
public function getLogActions() {
|
21 |
+
return Mage::getStoreConfig('mana_db/replicate/log_actions');
|
22 |
+
}
|
23 |
+
public function getSkipInserts() {
|
24 |
+
return Mage::getStoreConfig('mana_db/replicate/skip_inserts');
|
25 |
+
}
|
26 |
+
public function getSkipUpdates() {
|
27 |
+
return Mage::getStoreConfig('mana_db/replicate/skip_updates');
|
28 |
+
}
|
29 |
+
public function getSkipDeletes() {
|
30 |
+
return Mage::getStoreConfig('mana_db/replicate/skip_deletes');
|
31 |
+
}
|
32 |
+
public function getBatchSize() {
|
33 |
+
$result = Mage::getStoreConfig('mana_db/replicate/batch_size');
|
34 |
+
return $result ? $result : 10000;
|
35 |
+
}
|
36 |
+
public function getNoTransaction() {
|
37 |
+
return Mage::getStoreConfig('mana_db/replicate/no_transaction');
|
38 |
+
}
|
39 |
+
public function getMaxExecutionTime() {
|
40 |
+
return Mage::getStoreConfig('mana_db/replicate/max_execution_time');
|
41 |
+
}
|
42 |
+
public function getMemoryLimit() {
|
43 |
+
return Mage::getStoreConfig('mana_db/replicate/memory_limit');
|
44 |
}
|
45 |
public function logQuery($action, $query) {
|
46 |
if ($this->getLogQueries()) {
|
48 |
}
|
49 |
}
|
50 |
public function logAction($action, $object) {
|
51 |
+
if ($this->getLogActions()) {
|
52 |
Mage::log($action.': '.$object->toJson(), Zend_Log::DEBUG, 'replicate.log');
|
53 |
}
|
54 |
}
|
74 |
}
|
75 |
public function joinLeft($select, $alias, $table, $condition) {
|
76 |
if (!array_key_exists($alias, $select->getPart(Zend_Db_Select::FROM))) {
|
77 |
+
$select->joinLeft(array($alias => $table), $condition, null);
|
78 |
}
|
79 |
return $select;
|
80 |
}
|
129 |
$options = array_merge(array(
|
130 |
'db' => Mage::getSingleton('core/resource')->getConnection('core/write'),
|
131 |
'trackKeys' => false,
|
132 |
+
'transaction' => !$this->getNoTransaction(),
|
133 |
'filter' => array(),
|
134 |
+
'batchSize' => $this->getBatchSize(),
|
135 |
+
'object' => null,
|
136 |
), $options);
|
137 |
+
if ($this->getMaxExecutionTime()) {
|
138 |
+
ini_set('max_execution_time', $this->getMaxExecutionTime());
|
139 |
+
}
|
140 |
+
if ($this->getMemoryLimit()) {
|
141 |
+
ini_set('memory_limit', $this->getMemoryLimit());
|
142 |
+
}
|
143 |
if (count($options['filter']) == 0) {
|
144 |
$options['db']->resetDdlCache();
|
145 |
}
|
169 |
$model = Mage::getResourceSingleton($entityName);
|
170 |
|
171 |
// update existing rows
|
172 |
+
if (!$this->getSkipUpdates()) {
|
173 |
+
$target->setSelects(array())->setIsKeyFilterApplied(false);
|
174 |
+
$model->prepareReplicationUpdateSelects($target, $options);
|
175 |
+
if (count($target->getSelects()) && (!$options['trackKeys'] || $target->getIsKeyFilterApplied())) {
|
176 |
+
foreach ($target->getSelects() as $select) {
|
177 |
+
$offset = 0;
|
178 |
+
$this->logQuery('UPDATE', $select);
|
179 |
+
do {
|
180 |
+
$sourceData = $options['db']->fetchAll($select->limit($options['batchSize'], $offset));
|
181 |
+
if ($sourceData && count($sourceData)) {
|
182 |
+
foreach ($sourceData as $values) {
|
183 |
+
if ($object = $model->processReplicationUpdate($values, $options)) {
|
184 |
+
if ($object != $options['object']) {
|
185 |
+
$this->logAction('UPDATE', $object);
|
186 |
+
$object->save();
|
187 |
+
if ($options['trackKeys']) {
|
188 |
+
$target->setSavedKey($object->getId(), $object->getId());
|
189 |
+
}
|
190 |
+
}
|
191 |
+
else {
|
192 |
+
$object->unsetData('_m_prevent_replication');
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
$offset += $options['batchSize'];
|
198 |
+
} while ($sourceData && count($sourceData));
|
199 |
+
}
|
200 |
+
}
|
201 |
}
|
|
|
202 |
// insert rows
|
203 |
+
if (!$this->getSkipInserts()) {
|
204 |
+
$target->setSelects(array())->setIsKeyFilterApplied(false);
|
205 |
+
$model->prepareReplicationInsertSelects($target, $options);
|
206 |
+
if (count($target->getSelects()) && (!$options['trackKeys'] || $target->getIsKeyFilterApplied())) {
|
207 |
+
foreach ($target->getSelects() as $select) {
|
208 |
+
$offset = 0;
|
209 |
+
$this->logQuery('INSERT', $select);
|
210 |
+
do {
|
211 |
+
$sourceData = $options['db']->fetchAll($select->limit($options['batchSize']));
|
212 |
+
if ($sourceData && count($sourceData)) {
|
213 |
+
foreach ($sourceData as $values) {
|
214 |
+
if ($object = $model->processReplicationInsert($values, $options)) {
|
215 |
+
if ($object != $options['object']) {
|
216 |
+
$this->logAction('INSERT', $object);
|
217 |
+
$object->save();
|
218 |
+
if ($options['trackKeys']) {
|
219 |
+
$target->setSavedKey($object->getId(), $object->getId());
|
220 |
+
}
|
221 |
+
}
|
222 |
+
else {
|
223 |
+
$object->unsetData('_m_prevent_replication');
|
224 |
+
}
|
225 |
+
}
|
226 |
+
}
|
227 |
+
}
|
228 |
+
$offset += $options['batchSize'];
|
229 |
+
} while ($sourceData && count($sourceData));
|
230 |
+
}
|
231 |
+
}
|
232 |
}
|
|
|
233 |
// delete rows
|
234 |
+
if (!$this->getSkipDeletes()) {
|
235 |
+
$target->setSelects(array())->setIsKeyFilterApplied(false);
|
236 |
+
$model->prepareReplicationDeleteSelects($target, $options);
|
237 |
+
if (count($target->getSelects()) && (!$options['trackKeys'] || $target->getIsKeyFilterApplied())) {
|
238 |
+
foreach ($target->getSelects() as $select) {
|
239 |
+
$offset = 0;
|
240 |
+
$this->logQuery('DELETE', $select);
|
241 |
+
do {
|
242 |
+
$ids = $options['db']->fetchCol($select->limit($options['batchSize']));
|
243 |
+
if ($ids && count($ids)) {
|
244 |
+
$model->processReplicationDelete($ids, $options);
|
245 |
+
if ($options['trackKeys']) {
|
246 |
+
foreach ($ids as $id) {
|
247 |
+
$target->setDeletedKey($id, $id);
|
248 |
+
}
|
249 |
+
}
|
250 |
+
}
|
251 |
+
$offset += $options['batchSize'];
|
252 |
+
} while ($ids && count($ids));
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
}
|
257 |
+
}
|
258 |
+
|
259 |
if ($options['transaction']) {
|
260 |
$options['db']->commit();
|
261 |
}
|
364 |
return $a < $b ? -1 : 1;
|
365 |
}
|
366 |
|
367 |
+
public function isEditingSessionExpired($editSessionId) {
|
368 |
+
return Mage::getResourceSingleton('mana_db/edit_session')->isExpired($editSessionId);
|
369 |
+
}
|
370 |
protected $_inEditing = false;
|
371 |
public function getInEditing() {
|
372 |
return $this->_inEditing;
|
400 |
'deleted' => array(),
|
401 |
);
|
402 |
}
|
403 |
+
|
404 |
+
protected $_resourceSuffixes = array('_collection');
|
405 |
+
public function getSuffix ($entityName, $suffixes) {
|
406 |
+
/* @var $core Mana_Core_Helper_Data */
|
407 |
+
$core = Mage::helper(strtolower('Mana_Core'));
|
408 |
+
|
409 |
+
foreach ($suffixes as $candidateSuffix) {
|
410 |
+
if ($core->endsWith($entityName, $candidateSuffix)) {
|
411 |
+
return $candidateSuffix;
|
412 |
+
}
|
413 |
+
}
|
414 |
+
return '';
|
415 |
+
}
|
416 |
+
public function getScopedName($entityName) {
|
417 |
+
if ($suffix = $this->getSuffix($entityName, $this->_resourceSuffixes)) {
|
418 |
+
$entityName = substr($entityName, 0, strlen($entityName) - strlen($suffix));
|
419 |
+
}
|
420 |
+
|
421 |
+
$parts = explode('/', $entityName);
|
422 |
+
if (count($parts) > 2) {
|
423 |
+
if ($parts[2] == 'global') {
|
424 |
+
$entityName = "{$parts[0]}/{$parts[1]}";
|
425 |
+
}
|
426 |
+
else {
|
427 |
+
$entityName = "{$parts[0]}/{$parts[1]}_{$parts[2]}";
|
428 |
+
}
|
429 |
+
}
|
430 |
+
return $entityName . $suffix;
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* @param string $entityName
|
435 |
+
* @param array|null $arguments
|
436 |
+
* @return Mana_Db_Resource_Entity_Collection | Mana_Db_Resource_Entity
|
437 |
+
*/
|
438 |
+
public function getResourceModel($entityName, $arguments = null) {
|
439 |
+
if ($suffix = $this->getSuffix($entityName, $this->_resourceSuffixes)) {
|
440 |
+
$entityName = substr($entityName, 0, strlen($entityName) - strlen($suffix));
|
441 |
+
}
|
442 |
+
|
443 |
+
$arguments = array_merge(array(
|
444 |
+
'scope' => $entityName,
|
445 |
+
), $arguments ? (is_array($arguments) ? $arguments : array('resource' => $arguments)) : array());
|
446 |
+
|
447 |
+
|
448 |
+
$arguments = array_merge(array('scope' => $entityName), $arguments);
|
449 |
+
|
450 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
451 |
+
if ($this->resourceExists($resolvedEntityName . $suffix)) {
|
452 |
+
return Mage::getResourceModel($resolvedEntityName . $suffix, $arguments);
|
453 |
+
}
|
454 |
+
|
455 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
456 |
+
$dbConfig = Mage::helper('mana_db/config');
|
457 |
+
if (!($scopeXml = $dbConfig->getScopeXml($entityName))) {
|
458 |
+
return Mage::getResourceModel('mana_db/entity' . $suffix, $arguments);
|
459 |
+
}
|
460 |
+
|
461 |
+
if (!empty($scopeXml->flattens)) {
|
462 |
+
$entityName = (string)$scopeXml->flattens;
|
463 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
464 |
+
if ($this->resourceExists($resolvedEntityName . $suffix)) {
|
465 |
+
return Mage::getResourceModel($resolvedEntityName . $suffix, $arguments);
|
466 |
+
}
|
467 |
+
$scopeXml = $dbConfig->getScopeXml($entityName);
|
468 |
+
}
|
469 |
+
if (!empty($scopeXml->store_specifics_for)) {
|
470 |
+
$entityName = (string)$scopeXml->store_specifics_for;
|
471 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
472 |
+
if ($this->resourceExists($resolvedEntityName . $suffix)) {
|
473 |
+
return Mage::getResourceModel($resolvedEntityName . $suffix, $arguments);
|
474 |
+
}
|
475 |
+
}
|
476 |
+
|
477 |
+
return Mage::getResourceModel('mana_db/entity' . $suffix, $arguments);
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* @param string $entityName
|
482 |
+
* @param array | null $arguments
|
483 |
+
* @return Mana_Db_Resource_Entity
|
484 |
+
*/
|
485 |
+
public function getResourceSingleton($entityName, $arguments = null) {
|
486 |
+
if ($suffix = $this->getSuffix($entityName, $this->_resourceSuffixes)) {
|
487 |
+
$entityNameWithoutSuffix = substr($entityName, 0, strlen($entityName) - strlen($suffix));
|
488 |
+
}
|
489 |
+
else {
|
490 |
+
$entityNameWithoutSuffix = $entityName;
|
491 |
+
}
|
492 |
+
|
493 |
+
$arguments = array_merge(array(
|
494 |
+
'scope' => $entityNameWithoutSuffix,
|
495 |
+
), $arguments ? (is_array($arguments) ? $arguments : array('resource' => $arguments)) : array());
|
496 |
+
|
497 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
498 |
+
if ($this->resourceExists($resolvedEntityName)) {
|
499 |
+
return Mage::getResourceSingleton($resolvedEntityName, $arguments);
|
500 |
+
}
|
501 |
+
else {
|
502 |
+
if (!isset($this->_resourceSingletons[$resolvedEntityName])) {
|
503 |
+
$this->_resourceSingletons[$resolvedEntityName] = $this->getResourceModel($entityName, $arguments);
|
504 |
+
}
|
505 |
+
return $this->_resourceSingletons[$resolvedEntityName];
|
506 |
+
}
|
507 |
+
}
|
508 |
+
/**
|
509 |
+
* @param string $entityName
|
510 |
+
* @param array $arguments
|
511 |
+
* @return Mana_Db_Model_Entity
|
512 |
+
*/
|
513 |
+
public function getModel($entityName, $arguments = array()) {
|
514 |
+
$arguments = array_merge(array('scope' => $entityName), $arguments);
|
515 |
+
|
516 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
517 |
+
if ($this->modelExists($resolvedEntityName)) {
|
518 |
+
return Mage::getModel($resolvedEntityName, $arguments);
|
519 |
+
}
|
520 |
+
|
521 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
522 |
+
$dbConfig = Mage::helper('mana_db/config');
|
523 |
+
if (!($scopeXml = $dbConfig->getScopeXml($entityName))) {
|
524 |
+
return Mage::getModel('mana_db/entity', $arguments);
|
525 |
+
}
|
526 |
+
|
527 |
+
if (!empty($scopeXml->flattens)) {
|
528 |
+
$entityName = (string)$scopeXml->flattens;
|
529 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
530 |
+
if ($this->modelExists($resolvedEntityName)) {
|
531 |
+
return Mage::getModel($resolvedEntityName, $arguments);
|
532 |
+
}
|
533 |
+
$scopeXml = $dbConfig->getScopeXml($entityName);
|
534 |
+
}
|
535 |
+
if (!empty($scopeXml->store_specifics_for)) {
|
536 |
+
$entityName = (string)$scopeXml->store_specifics_for;
|
537 |
+
$resolvedEntityName = $this->getScopedName($entityName);
|
538 |
+
if ($this->modelExists($resolvedEntityName)) {
|
539 |
+
return Mage::getModel($resolvedEntityName, $arguments);
|
540 |
+
}
|
541 |
+
}
|
542 |
+
return Mage::getModel('mana_db/entity', $arguments);
|
543 |
+
}
|
544 |
+
|
545 |
+
public function resourceExists($entityName) {
|
546 |
+
if ($className = Mage::getConfig()->getResourceModelClassName($entityName)) {
|
547 |
+
return $this->classExists($className);
|
548 |
+
}
|
549 |
+
else {
|
550 |
+
return false;
|
551 |
+
}
|
552 |
+
|
553 |
+
}
|
554 |
+
|
555 |
+
public function modelExists($entityName) {
|
556 |
+
if ($className = Mage::getConfig()->getModelClassName($entityName)) {
|
557 |
+
return $this->classExists($className);
|
558 |
+
}
|
559 |
+
else {
|
560 |
+
return false;
|
561 |
+
}
|
562 |
+
|
563 |
+
}
|
564 |
+
|
565 |
+
public function classExists($class) {
|
566 |
+
if (defined('COMPILER_INCLUDE_PATH')) {
|
567 |
+
$classFile = $class;
|
568 |
+
}
|
569 |
+
else {
|
570 |
+
$classFile = str_replace(' ', DIRECTORY_SEPARATOR, ucwords(str_replace('_', ' ', $class)));
|
571 |
+
}
|
572 |
+
$classFile .= '.php';
|
573 |
+
foreach (explode(PS, get_include_path()) as $path) {
|
574 |
+
if (file_exists($path.DS.$classFile)) {
|
575 |
+
return true;
|
576 |
+
}
|
577 |
+
}
|
578 |
+
|
579 |
+
return false;
|
580 |
+
}
|
581 |
}
|
app/code/local/Mana/Db/Helper/Formula.php
ADDED
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula extends Mage_Core_Helper_Abstract {
|
13 |
+
protected $_orders;
|
14 |
+
static $_types = array(
|
15 |
+
'varchar' => 'string',
|
16 |
+
'mediumtext' => 'string',
|
17 |
+
'text' => 'string',
|
18 |
+
'tinyint' => 'int',
|
19 |
+
'smallint' => 'int',
|
20 |
+
'int' => 'int',
|
21 |
+
'bigint' => 'int',
|
22 |
+
);
|
23 |
+
static $_numericTypes = array(
|
24 |
+
8 => 'tinyint',
|
25 |
+
16 => 'smallint',
|
26 |
+
32 => 'int',
|
27 |
+
);
|
28 |
+
|
29 |
+
protected $_typeCache = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param string $entity
|
33 |
+
* @param string[] $formulas
|
34 |
+
* @param array $options
|
35 |
+
* @throws Exception|Mana_Db_Exception_Formula
|
36 |
+
* @return Mana_Db_Model_Formula_Context
|
37 |
+
*/
|
38 |
+
public function select($entity, $formulas, $options = array()) {
|
39 |
+
$options = array_merge(array(
|
40 |
+
'process_all_fields' => true,
|
41 |
+
), $options);
|
42 |
+
|
43 |
+
/* @var $select Varien_Db_Select */
|
44 |
+
/* @var $selector Mana_Db_Helper_Formula_Selector */
|
45 |
+
/* @var $context Mana_Db_Model_Formula_Context */
|
46 |
+
$this->_initSelect($entity, $options, $select, $context, $selector);
|
47 |
+
|
48 |
+
// process formulas
|
49 |
+
foreach ($this->_getFieldFormulas($context, $formulas, $options) as $field) {
|
50 |
+
$context->setField($field);
|
51 |
+
try {
|
52 |
+
if ($field->getRole()) {
|
53 |
+
if ($field->hasFormula()) {
|
54 |
+
$selector->selectFormula($context, $field->getFormula());
|
55 |
+
$context->addField($field->getName());
|
56 |
+
}
|
57 |
+
else {
|
58 |
+
if ($selector->selectSystemField($context)) {
|
59 |
+
$context->addField($field->getName());
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
+
elseif ($field->hasFormula()) {
|
64 |
+
$selector->selectFormula($context, $field->getFormula());
|
65 |
+
$context->addField($field->getName());
|
66 |
+
}
|
67 |
+
elseif ($field->hasValue()) {
|
68 |
+
$selector->selectValue($context, $field->getValue());
|
69 |
+
$context->addField($field->getName());
|
70 |
+
}
|
71 |
+
else {
|
72 |
+
$selector->selectDefaultValue($context);
|
73 |
+
$context->addField($field->getName());
|
74 |
+
}
|
75 |
+
}
|
76 |
+
catch (Mana_Db_Exception_Formula $e) {
|
77 |
+
if ($context->getOption('provide_field_details_in_exceptions')) {
|
78 |
+
if ($field->hasFormula()) {
|
79 |
+
$e->addMessage($this->__(" in entity: '%s', field: '%s', formula '%s'", $entity, $field->getName(), $field->getFormulaString()));
|
80 |
+
}
|
81 |
+
else {
|
82 |
+
$e->addMessage($this->__(" in entity: '%s', field: '%s'", $entity, $field->getName()));
|
83 |
+
}
|
84 |
+
}
|
85 |
+
throw $e;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
return $context;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @param Mana_Db_Model_Entity $model
|
94 |
+
* @return mixed
|
95 |
+
*/
|
96 |
+
public function evaluate($model) {
|
97 |
+
/* @var $evaluator Mana_Db_Helper_Formula_Evaluator */
|
98 |
+
$evaluator = Mage::helper('mana_db/formula_evaluator');
|
99 |
+
|
100 |
+
/* @var $context Mana_Db_Model_Formula_Context */
|
101 |
+
$context = Mage::getModel('mana_db/formula_context');
|
102 |
+
$context
|
103 |
+
->setEntity($model->getScope())
|
104 |
+
->setModel($model)
|
105 |
+
->setProcessor('entity')
|
106 |
+
->setHelper($evaluator);
|
107 |
+
|
108 |
+
if ($defaultFormulas = $model->getDefaultFormulas()) {
|
109 |
+
$defaultFormulas = json_decode($defaultFormulas, true);
|
110 |
+
}
|
111 |
+
else {
|
112 |
+
$defaultFormulas = array();
|
113 |
+
}
|
114 |
+
|
115 |
+
foreach ($this->_getFieldFormulas($context, $defaultFormulas) as $field) {
|
116 |
+
if ($field->useDefault($model)) {
|
117 |
+
if ($field->hasFormula()) {
|
118 |
+
$evaluator->evaluateFormula($context, $field);
|
119 |
+
}
|
120 |
+
elseif ($field->hasValue()) {
|
121 |
+
$evaluator->evaluateValue($context, $field);
|
122 |
+
}
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
return $context->getResult();
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* @param $formula
|
131 |
+
* @return Mana_Db_Model_Formula_Node
|
132 |
+
*/
|
133 |
+
public function parse($formula) {
|
134 |
+
/* @var $parser Mana_Db_Helper_Formula_Parser */
|
135 |
+
$parser = Mage::helper('mana_db/formula_parser');
|
136 |
+
|
137 |
+
return $parser->parse($formula);
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @param Mana_Db_Model_Formula_Context $context
|
142 |
+
* @param Mana_Db_Model_Formula_Node $formula
|
143 |
+
* @return string[]
|
144 |
+
*/
|
145 |
+
public function depends($context, $formula) {
|
146 |
+
/* @var $dependencyFinder Mana_Db_Helper_Formula_DependencyFinder */
|
147 |
+
$dependencyFinder = Mage::helper('mana_db/formula_dependencyFinder');
|
148 |
+
return $dependencyFinder->findInFormula($context, $formula);
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
public function getFormulaGroups($entity, $options = array()) {
|
153 |
+
/* @var $select Varien_Db_Select */
|
154 |
+
/* @var $selector Mana_Db_Helper_Formula_Selector */
|
155 |
+
/* @var $context Mana_Db_Model_Formula_Context */
|
156 |
+
$this->_initSelect($entity, $options, $select, $context, $selector);
|
157 |
+
$idExpr = "`{$context->registerAlias('primary')}`.`id`";
|
158 |
+
$hashExpr = "`{$context->registerAlias('primary')}`.`default_formula_hash`";
|
159 |
+
$formulasExpr = "`{$context->registerAlias('primary')}`.`default_formulas`";
|
160 |
+
|
161 |
+
|
162 |
+
$select
|
163 |
+
->distinct()
|
164 |
+
->columns(array('id' => new Zend_Db_Expr("MIN($idExpr)")))
|
165 |
+
->columns(array('hash' => new Zend_Db_Expr("$hashExpr")))
|
166 |
+
->group('hash');
|
167 |
+
|
168 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
169 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
170 |
+
$db = $resource->getReadConnection();
|
171 |
+
$hashes = $db->fetchPairs($select);
|
172 |
+
if (($nullId = array_search(null, $hashes)) !== false) {
|
173 |
+
unset($hashes[$nullId]);
|
174 |
+
}
|
175 |
+
|
176 |
+
if (count($hashes)) {
|
177 |
+
$this->_initSelect($entity, $options, $select, $context, $selector);
|
178 |
+
$select
|
179 |
+
->columns(array('id' => new Zend_Db_Expr("$idExpr")))
|
180 |
+
->columns(array('formulas' => new Zend_Db_Expr("$formulasExpr")))
|
181 |
+
->where("$idExpr IN (?)", array_keys($hashes));
|
182 |
+
|
183 |
+
$formulas = $db->fetchPairs($select);
|
184 |
+
|
185 |
+
$result = array_combine($hashes, $formulas);
|
186 |
+
}
|
187 |
+
else {
|
188 |
+
$result = array();
|
189 |
+
}
|
190 |
+
if ($nullId !== false) {
|
191 |
+
$result[''] = '';
|
192 |
+
}
|
193 |
+
return $result;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* @param string $entity
|
198 |
+
* @param string $targetEntity
|
199 |
+
* @param array $options
|
200 |
+
* @throws Exception
|
201 |
+
* @return string
|
202 |
+
*/
|
203 |
+
public function delete($entity, $targetEntity, $options = array()) {
|
204 |
+
throw new Exception('Not implemented');
|
205 |
+
/* @var $select Varien_Db_Select */
|
206 |
+
/* @var $selector Mana_Db_Helper_Formula_Selector */
|
207 |
+
/* @var $context Mana_Db_Model_Formula_Context */
|
208 |
+
$this->_initSelect($entity, $options, $select, $context, $selector);
|
209 |
+
|
210 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
211 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
212 |
+
|
213 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
214 |
+
$dbHelper = Mage::helper('mana_db');
|
215 |
+
|
216 |
+
$select->setPart(Varien_Db_Select::FROM, array());
|
217 |
+
return $select->deleteFromSelect($resource->getTable($dbHelper->getScopedName($targetEntity)));
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* @param string $entity
|
222 |
+
* @param array $options
|
223 |
+
* @param Varien_Db_Select $select
|
224 |
+
* @param Mana_Db_Model_Formula_Context $context
|
225 |
+
* @param Mana_Db_Helper_Formula_Selector $selector
|
226 |
+
*/
|
227 |
+
protected function _initSelect($entity, $options, &$select, &$context, &$selector) {
|
228 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
229 |
+
$dbConfig = Mage::helper('mana_db/config');
|
230 |
+
|
231 |
+
$scopeXml = $dbConfig->getScopeXml($entity);
|
232 |
+
|
233 |
+
/* @var $selector Mana_Db_Helper_Formula_Selector */
|
234 |
+
$selector = Mage::helper('mana_db/formula_selector');
|
235 |
+
|
236 |
+
/* @var $normalEntity Mana_Db_Helper_Formula_Entity_Normal */
|
237 |
+
$normalEntity = Mage::helper('mana_db/formula_entity_normal');
|
238 |
+
|
239 |
+
/* @var $context Mana_Db_Model_Formula_Context */
|
240 |
+
$context = Mage::getModel('mana_db/formula_context');
|
241 |
+
|
242 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
243 |
+
$context
|
244 |
+
->setAlias($this->createAlias(''))
|
245 |
+
->setEntity($entity)
|
246 |
+
->setPrimaryEntity((string)$scopeXml->flattens)
|
247 |
+
->setTargetEntity($entity)
|
248 |
+
->setProcessor('entity')
|
249 |
+
->setEntityHelper($normalEntity)
|
250 |
+
->setHelper($selector)
|
251 |
+
->setOptions($options);
|
252 |
+
|
253 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
254 |
+
$select = $this->createSelect($context, $scopeXml->formula->base);
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* @param Mana_Db_Model_Formula_Context $context
|
259 |
+
* @param string[] $formulas
|
260 |
+
* @return Mana_Db_Model_Formula_Field[]
|
261 |
+
*/
|
262 |
+
protected function _getFieldFormulas($context, $formulas, $options = array()) {
|
263 |
+
$result = array();
|
264 |
+
$entity = $context->getTargetEntity();
|
265 |
+
|
266 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
267 |
+
$dbConfig = Mage::helper('mana_db/config');
|
268 |
+
|
269 |
+
/* @var $fieldsXml Varien_Simplexml_Element */
|
270 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
271 |
+
$fieldsXml = $dbConfig->getScopeXml($entity)->fields;
|
272 |
+
foreach ($fieldsXml->children() as $name => $fieldXml) {
|
273 |
+
if (empty($options['process_all_fields']) && !isset($formulas[$name])) {
|
274 |
+
continue;
|
275 |
+
}
|
276 |
+
/* @var $field Mana_Db_Model_Formula_Field */
|
277 |
+
$field = Mage::getModel('mana_db/formula_field');
|
278 |
+
$field
|
279 |
+
->setName($name)
|
280 |
+
->setRole(isset($fieldXml->role) ? (string)$fieldXml->role : '')
|
281 |
+
->setType((string)$fieldXml->type);
|
282 |
+
|
283 |
+
if (isset($fieldXml->no)) {
|
284 |
+
$field->setNo((string)$fieldXml->no);
|
285 |
+
}
|
286 |
+
if (isset($formulas[$name])) {
|
287 |
+
$field
|
288 |
+
->setFormulaString($formulas[$name])
|
289 |
+
->setFormula($this->parse($formulas[$name]))
|
290 |
+
->setDependencies($this->depends($context, $field->getFormula()));
|
291 |
+
}
|
292 |
+
elseif(isset($fieldXml->default_formula)) {
|
293 |
+
$field
|
294 |
+
->setFormulaString((string)$fieldXml->default_formula)
|
295 |
+
->setFormula($this->parse((string)$fieldXml->default_formula))
|
296 |
+
->setDependencies($this->depends($context, $field->getFormula()));
|
297 |
+
}
|
298 |
+
elseif (isset($fieldXml->default_value)) {
|
299 |
+
$field->setValue((string)$fieldXml->default_value);
|
300 |
+
}
|
301 |
+
$result[$name] = $field;
|
302 |
+
}
|
303 |
+
|
304 |
+
$this->_sortByDependency($result);
|
305 |
+
return $result;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* @param Mana_Db_Model_Formula_Field[] $fields
|
310 |
+
* @throws Mana_Db_Exception_Formula
|
311 |
+
* @return Mana_Db_Helper_Formula
|
312 |
+
*/
|
313 |
+
protected function _sortByDependency(&$fields) {
|
314 |
+
$count = count($fields);
|
315 |
+
$orders = array();
|
316 |
+
for ($position = 0; $position < $count; $position++) {
|
317 |
+
$found = false;
|
318 |
+
foreach ($fields as $fieldName => $field) {
|
319 |
+
if (!isset($orders[$fieldName])) {
|
320 |
+
$hasUnresolvedDependency = false;
|
321 |
+
if ($field->hasDependencies()) {
|
322 |
+
foreach ($field->getDependencies() as $dependency) {
|
323 |
+
if (!isset($fields[$dependency])) {
|
324 |
+
throw new Mana_Db_Exception_Formula(Mage::helper('mana_db')->__("Field '%s' depends on undefined field '%s'", $fieldName, $dependency));
|
325 |
+
}
|
326 |
+
if (!isset($orders[$dependency])) {
|
327 |
+
// $dependency not yet sorted so $module should wait until that happens
|
328 |
+
$hasUnresolvedDependency = true;
|
329 |
+
break;
|
330 |
+
}
|
331 |
+
}
|
332 |
+
}
|
333 |
+
if (!$hasUnresolvedDependency) {
|
334 |
+
$found = $fieldName;
|
335 |
+
break;
|
336 |
+
}
|
337 |
+
}
|
338 |
+
}
|
339 |
+
if ($found) {
|
340 |
+
$orders[$found] = count($orders);
|
341 |
+
}
|
342 |
+
else {
|
343 |
+
$circular = array();
|
344 |
+
foreach ($fields as $fieldName => $field) {
|
345 |
+
if (!isset($orders[$fieldName])) {
|
346 |
+
$circular[] = $fieldName;
|
347 |
+
}
|
348 |
+
}
|
349 |
+
throw new Mana_Db_Exception_Formula(Mage::helper('mana_db')->__('Field values circularly depends on one another: %s', implode(', ', $circular)));
|
350 |
+
}
|
351 |
+
}
|
352 |
+
$this->_orders = $orders;
|
353 |
+
uasort($fields, array($this, '_sortByDependencyCallback'));
|
354 |
+
|
355 |
+
return $this;
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* @param Mana_Db_Model_Formula_Field $a
|
360 |
+
* @param Mana_Db_Model_Formula_Field $b
|
361 |
+
* @return int
|
362 |
+
*/
|
363 |
+
protected function _sortByDependencyCallback($a, $b) {
|
364 |
+
$a = $this->_orders[$a->getName()];
|
365 |
+
$b = $this->_orders[$b->getName()];
|
366 |
+
if ($a == $b) return 0;
|
367 |
+
|
368 |
+
return $a < $b ? -1 : 1;
|
369 |
+
}
|
370 |
+
|
371 |
+
public function getType($sqlType) {
|
372 |
+
if (!isset($this->_typeCache[$sqlType])) {
|
373 |
+
$type = trim(strtolower($sqlType));
|
374 |
+
$pos = false;
|
375 |
+
if (($foundPos = strpos($type, '(')) !== false) {
|
376 |
+
$pos = $foundPos;
|
377 |
+
}
|
378 |
+
if (($foundPos = strpos($type, ' ')) !== false) {
|
379 |
+
$pos = $foundPos;
|
380 |
+
}
|
381 |
+
if ($pos !== false) {
|
382 |
+
$type = substr($type, 0, $pos);
|
383 |
+
}
|
384 |
+
|
385 |
+
$this->_typeCache[$sqlType] = isset(self::$_types[$type]) ? self::$_types[$type] : '';
|
386 |
+
}
|
387 |
+
return $this->_typeCache[$sqlType];
|
388 |
+
}
|
389 |
+
|
390 |
+
public function getMinimumNumericType($value) {
|
391 |
+
foreach (self::$_numericTypes as $bit => $type) {
|
392 |
+
if (abs($value) < 1 << $bit - 1) {
|
393 |
+
return $type;
|
394 |
+
}
|
395 |
+
}
|
396 |
+
return 'bigint';
|
397 |
+
}
|
398 |
+
|
399 |
+
/**
|
400 |
+
* @param Mana_Db_Model_Formula_Context $context
|
401 |
+
* @param SimpleXMLElement $selectXml
|
402 |
+
* @return Varien_Db_Select
|
403 |
+
*/
|
404 |
+
public function createSelect($context, $selectXml) {
|
405 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
406 |
+
$dbHelper = Mage::helper('mana_db');
|
407 |
+
|
408 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
409 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
410 |
+
|
411 |
+
$select = $context->getSelect();
|
412 |
+
|
413 |
+
/* @var $fromXml SimpleXMLElement */
|
414 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
415 |
+
$fromXml = $selectXml->from;
|
416 |
+
foreach ($fromXml->children() as $alias => $definition) {
|
417 |
+
$entity = $alias == 'primary' ? $context->getPrimaryEntity() : (string)$definition->entity;
|
418 |
+
$select->from(
|
419 |
+
array($context->registerAlias($alias) => $resource->getTable($dbHelper->getScopedName($entity))),
|
420 |
+
null
|
421 |
+
);
|
422 |
+
}
|
423 |
+
|
424 |
+
if (isset($selectXml->join)) {
|
425 |
+
$joinXml = $selectXml->join;
|
426 |
+
/* @var $joinXml SimpleXMLElement */
|
427 |
+
foreach ($joinXml->children() as $alias => $definition) {
|
428 |
+
$method = isset($definition->type) ? 'join' . ucfirst($definition->type) : 'joinInner';
|
429 |
+
$entity = $alias == 'primary' ? $context->getPrimaryEntity() : (string)$definition->entity;
|
430 |
+
$select->$method(
|
431 |
+
array($context->registerAlias($alias) => $resource->getTable($dbHelper->getScopedName($entity))),
|
432 |
+
$context->resolveAliases((string)$definition->on),
|
433 |
+
null
|
434 |
+
);
|
435 |
+
}
|
436 |
+
}
|
437 |
+
|
438 |
+
if (isset($selectXml->order)) {
|
439 |
+
$select->order($context->resolveAliases((string)$selectXml->order, false));
|
440 |
+
|
441 |
+
}
|
442 |
+
if (isset($selectXml->where)) {
|
443 |
+
$select->where($context->resolveAliases((string)$selectXml->where));
|
444 |
+
|
445 |
+
}
|
446 |
+
|
447 |
+
if ($formula = $context->getOption('entity_filter_formula')) {
|
448 |
+
/* @var $selector Mana_Db_Helper_Formula_Selector */
|
449 |
+
$selector = Mage::helper('mana_db/formula_selector');
|
450 |
+
$selector->filterFormula($context, $this->parse($formula), $context->getOption('entity_filter_id'));
|
451 |
+
}
|
452 |
+
|
453 |
+
return $select;
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* @param string | string[] $value
|
458 |
+
* @return Mana_Db_Model_Formula_Alias
|
459 |
+
*/
|
460 |
+
public function createAlias($value) {
|
461 |
+
if (!$value || $value == 'this') {
|
462 |
+
return Mage::getModel('mana_db/formula_alias_empty');
|
463 |
+
}
|
464 |
+
elseif (is_array($value)) {
|
465 |
+
return Mage::getModel('mana_db/formula_alias_array', $value);
|
466 |
+
}
|
467 |
+
else {
|
468 |
+
return Mage::getModel('mana_db/formula_alias_single', $value);
|
469 |
+
}
|
470 |
+
}
|
471 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Abstract.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Abstract extends Mage_Core_Helper_Abstract {
|
13 |
+
const CLASS_PREFIX = 'Mana_Db_Model_Formula_Node_';
|
14 |
+
protected $_methodPrefix = '';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var Mana_Db_Model_Formula_Expr
|
18 |
+
*/
|
19 |
+
protected $_exprPrototype;
|
20 |
+
|
21 |
+
public function __construct() {
|
22 |
+
$this->_exprPrototype = Mage::getModel('mana_db/formula_expr');
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return Mana_Db_Model_Formula_Expr
|
27 |
+
*/
|
28 |
+
public function expr() {
|
29 |
+
return clone $this->_exprPrototype;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
34 |
+
* @param string $type
|
35 |
+
* @return Mana_Db_Model_Formula_Expr
|
36 |
+
*/
|
37 |
+
public function cast($expr, $type) {
|
38 |
+
return $expr;
|
39 |
+
}
|
40 |
+
|
41 |
+
public function _call($args) {
|
42 |
+
/* @var $core Mana_Core_Helper_Data */
|
43 |
+
$core = Mage::helper('mana_core');
|
44 |
+
$formula = $args[1];
|
45 |
+
$class = get_class($formula);
|
46 |
+
if ($core->startsWith($class, self::CLASS_PREFIX)) {
|
47 |
+
return call_user_func_array(array($this, $this->_methodPrefix . substr($class, strlen(self::CLASS_PREFIX))), $args);
|
48 |
+
}
|
49 |
+
else {
|
50 |
+
throw new $this->__("Formula node class must start with '%s'", self::CLASS_PREFIX);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
public function __call($name, $args) {
|
55 |
+
/* @var $core Mana_Core_Helper_Data */
|
56 |
+
$core = Mage::helper('mana_core');
|
57 |
+
|
58 |
+
if ($core->startsWith($name, $this->_methodPrefix)) {
|
59 |
+
return call_user_func_array(array($this, $this->_methodPrefix . 'Node'), $args);
|
60 |
+
}
|
61 |
+
else {
|
62 |
+
throw new $this->__("Unknown method %s::%s", __CLASS__, $name);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @param string $name
|
68 |
+
* @return Mana_Db_Helper_Formula_Function
|
69 |
+
*/
|
70 |
+
public function getFunction($name) {
|
71 |
+
return Mage::helper('mana_db/formula_function_' . lcfirst(uc_words(strtolower($name), '')));
|
72 |
+
}
|
73 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/DependencyFinder.php
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_DependencyFinder extends Mana_Db_Helper_Formula_Abstract {
|
13 |
+
protected $_methodPrefix = '_findIn';
|
14 |
+
/**
|
15 |
+
* @param Mana_Db_Model_Formula_Context $context
|
16 |
+
* @param Mana_Db_Model_Formula_Node $formula
|
17 |
+
* @return string[]
|
18 |
+
*/
|
19 |
+
public function findInFormula(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
20 |
+
return $this->_call(func_get_args());
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param Mana_Db_Model_Formula_Context $context
|
25 |
+
* @param Mana_Db_Model_Formula_Node_Add $formula
|
26 |
+
* @return string[]
|
27 |
+
*/
|
28 |
+
protected function _findInAdd($context, $formula) {
|
29 |
+
return array_merge($this->findInFormula($context, $formula->a), $this->findInFormula($context, $formula->b));
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param Mana_Db_Model_Formula_Context $context
|
34 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
35 |
+
* @return string[]
|
36 |
+
*/
|
37 |
+
protected function _findInField(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
38 |
+
if (count($formula->identifiers) == 2 && $formula->identifiers[0] == 'this') {
|
39 |
+
return array($formula->identifiers[1]);
|
40 |
+
}
|
41 |
+
else {
|
42 |
+
return array();
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param Mana_Db_Model_Formula_Context $context
|
48 |
+
* @param Mana_Db_Model_Formula_Node_FormulaExpr $formula
|
49 |
+
* @return string[]
|
50 |
+
*/
|
51 |
+
protected function _findInFormulaExpr($context, $formula) {
|
52 |
+
$result = array();
|
53 |
+
foreach ($formula->parts as $part) {
|
54 |
+
$result = array_merge($result, $this->findInFormula($context, $part));
|
55 |
+
}
|
56 |
+
return $result;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param Mana_Db_Model_Formula_Context $context
|
61 |
+
* @param Mana_Db_Model_Formula_Node_FunctionCall $formula
|
62 |
+
* @return string[]
|
63 |
+
*/
|
64 |
+
protected function _findInFunctionCall($context, $formula) {
|
65 |
+
$result = array();
|
66 |
+
foreach ($formula->args as $arg) {
|
67 |
+
$result = array_merge($result, $this->findInFormula($context, $arg));
|
68 |
+
}
|
69 |
+
|
70 |
+
return $result;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param Mana_Db_Model_Formula_Context $context
|
75 |
+
* @param Mana_Db_Model_Formula_Node_Identifier $formula
|
76 |
+
* @return string[]
|
77 |
+
*/
|
78 |
+
protected function _findInIdentifier(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
79 |
+
return array($formula->identifier);
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @param Mana_Db_Model_Formula_Context $context
|
84 |
+
* @param Mana_Db_Model_Formula_Node_Multiply $formula
|
85 |
+
* @return string[]
|
86 |
+
*/
|
87 |
+
protected function _findInMultiply($context, $formula) {
|
88 |
+
return array_merge($this->findInFormula($context, $formula->a), $this->findInFormula($context, $formula->b));
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param Mana_Db_Model_Formula_Context $context
|
93 |
+
* @param Mana_Db_Model_Formula_Node $formula
|
94 |
+
* @return string[]
|
95 |
+
*/
|
96 |
+
protected function _findInNode(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
97 |
+
return array();
|
98 |
+
}
|
99 |
+
|
100 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Entity.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
abstract class Mana_Db_Helper_Formula_Entity extends Mage_Core_Helper_Abstract {
|
13 |
+
protected $_name;
|
14 |
+
|
15 |
+
/**
|
16 |
+
*
|
17 |
+
* @param Mana_Db_Model_Formula_Context $context
|
18 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
19 |
+
*/
|
20 |
+
public abstract function select($context, $entity);
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @param Mana_Db_Model_Formula_Context $context
|
24 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
25 |
+
*/
|
26 |
+
public function endSelect($context, $entity) {
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @param Mana_Db_Model_Formula_Context $context
|
31 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
32 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
33 |
+
*/
|
34 |
+
public abstract function selectField($context, $formula, $expr);
|
35 |
+
|
36 |
+
public function getName() {
|
37 |
+
if (!$this->_name) {
|
38 |
+
$class = substr(get_class($this), strlen(__CLASS__ . '_'));
|
39 |
+
$this->_name = strtolower($class);
|
40 |
+
}
|
41 |
+
|
42 |
+
return $this->_name;
|
43 |
+
}
|
44 |
+
|
45 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Entity/Aggregate.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Entity_Aggregate extends Mana_Db_Helper_Formula_Entity {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
16 |
+
*/
|
17 |
+
public function select($context, $entity) {
|
18 |
+
switch ($context->getMode()) {
|
19 |
+
default:
|
20 |
+
$context
|
21 |
+
->setMode($this->getName())
|
22 |
+
->setEntityHelper($this);
|
23 |
+
|
24 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
25 |
+
$dbHelper = Mage::helper('mana_db');
|
26 |
+
|
27 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
28 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
29 |
+
|
30 |
+
$context->incrementPrefix();
|
31 |
+
|
32 |
+
$alias = explode('.', $entity->getAlias());
|
33 |
+
$alias = array_pop($alias);
|
34 |
+
|
35 |
+
$aggregateContext = $context->createChildContext()
|
36 |
+
->setPrefix($context->getPrefix())
|
37 |
+
->setEntity($entity->getEntity())
|
38 |
+
->setProcessor($entity->getProcessor())
|
39 |
+
->setAlias($alias);
|
40 |
+
|
41 |
+
$select = $aggregateContext->getSelect()
|
42 |
+
->from(array(
|
43 |
+
$aggregateContext->registerAlias($alias)
|
44 |
+
=> $resource->getTable($dbHelper->getScopedName($entity->getEntity()))
|
45 |
+
), null);
|
46 |
+
|
47 |
+
if ($entity->getJoin()) {
|
48 |
+
foreach ($entity->getJoin() as $alias => $join) {
|
49 |
+
$method = isset($join['type']) ? 'join' . ucfirst($join['type']) : 'joinInner';
|
50 |
+
$select->$method(
|
51 |
+
array(
|
52 |
+
$aggregateContext->registerAlias($alias) =>
|
53 |
+
$resource->getTable($dbHelper->getScopedName($join['entity']))
|
54 |
+
),
|
55 |
+
$aggregateContext->resolveAliases($join['on']),
|
56 |
+
null
|
57 |
+
);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
if ($entity->getOrder()) {
|
61 |
+
$select->order($aggregateContext->resolveAliases($entity->getOrder(), false));
|
62 |
+
}
|
63 |
+
if ($entity->getWhere()) {
|
64 |
+
$select->where($aggregateContext->resolveAliases($entity->getWhere()));
|
65 |
+
}
|
66 |
+
|
67 |
+
$context
|
68 |
+
->setEntity($entity->getEntity())
|
69 |
+
->setProcessor($entity->getProcessor())
|
70 |
+
->setAlias($entity->getAlias())
|
71 |
+
->setAggregateContext($aggregateContext);
|
72 |
+
break;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param Mana_Db_Model_Formula_Context $context
|
78 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
79 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
80 |
+
*/
|
81 |
+
public function selectField($context, $formula, $expr) {
|
82 |
+
$expr
|
83 |
+
->setIsAggregate(true)
|
84 |
+
->setSubSelect($context->getAggregateContext()->getSelect());
|
85 |
+
}
|
86 |
+
|
87 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Entity/Aggregate/Field.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Entity_Aggregate_Field extends Mana_Db_Helper_Formula_Entity {
|
13 |
+
/**
|
14 |
+
*
|
15 |
+
* @param Mana_Db_Model_Formula_Context $context
|
16 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
17 |
+
*/
|
18 |
+
public function select($context, $entity) {
|
19 |
+
switch ($context->getMode()) {
|
20 |
+
default:
|
21 |
+
$context
|
22 |
+
->setMode($this->getName())
|
23 |
+
->setEntityHelper($this);
|
24 |
+
|
25 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
26 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
27 |
+
|
28 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
29 |
+
$dbHelper = Mage::helper('mana_db');
|
30 |
+
|
31 |
+
foreach ($entity->getAggregateFields() as $field) {
|
32 |
+
if (!$context->hasAlias($field['alias'])) {
|
33 |
+
$context->getSelect()->joinLeft(
|
34 |
+
array(
|
35 |
+
$context->registerAlias($field['alias']) =>
|
36 |
+
$resource->getTable($dbHelper->getScopedName($field['entity']))
|
37 |
+
),
|
38 |
+
$context->resolveAliases($field['join']),
|
39 |
+
null
|
40 |
+
);
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
$context
|
45 |
+
->setEntity($entity->getEntity())
|
46 |
+
->setProcessor($entity->getProcessor())
|
47 |
+
->setAlias($entity->getAlias());
|
48 |
+
break;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @param Mana_Db_Model_Formula_Context $context
|
54 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
55 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
56 |
+
*/
|
57 |
+
public function selectField($context, $formula, $expr) {
|
58 |
+
$expr->setIsAggregate(true);
|
59 |
+
}
|
60 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Entity/Foreign.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Entity_Foreign extends Mana_Db_Helper_Formula_Entity {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
16 |
+
*/
|
17 |
+
public function select($context, $entity) {
|
18 |
+
switch ($context->getMode()) {
|
19 |
+
default:
|
20 |
+
if (!$context->hasAlias($entity->getAlias()->asString(0))) {
|
21 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
22 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
23 |
+
|
24 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
25 |
+
$dbHelper = Mage::helper('mana_db');
|
26 |
+
|
27 |
+
/* @var $joinClosure Mana_Db_Model_Formula_Closure_ForeignJoinEnd */
|
28 |
+
$joinClosure = Mage::getModel('mana_db/formula_closure_foreignJoinEnd', compact('context', 'entity'));
|
29 |
+
$context->getAlias()->each($joinClosure);
|
30 |
+
}
|
31 |
+
|
32 |
+
$context
|
33 |
+
->setEntity($entity->getEntity())
|
34 |
+
->setProcessor($entity->getProcessor())
|
35 |
+
->setAlias($entity->getAlias())
|
36 |
+
->setEntityHelper($this);
|
37 |
+
break;
|
38 |
+
}
|
39 |
+
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param Mana_Db_Model_Formula_Context $context
|
44 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
45 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
46 |
+
*/
|
47 |
+
public function selectField($context, $formula, $expr) {
|
48 |
+
$expr->setExpr($expr->getFieldExpr());
|
49 |
+
}
|
50 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Entity/Frontend.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Entity_Frontend extends Mana_Db_Helper_Formula_Entity {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
16 |
+
*/
|
17 |
+
public function select($context, $entity) {
|
18 |
+
switch ($context->getMode()) {
|
19 |
+
default:
|
20 |
+
$context
|
21 |
+
->setMode($this->getName())
|
22 |
+
->setEntityHelper($this);
|
23 |
+
|
24 |
+
$context
|
25 |
+
->setEntity($entity->getEntity())
|
26 |
+
->setProcessor($entity->getProcessor())
|
27 |
+
->setAlias($entity->getAlias());
|
28 |
+
break;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param Mana_Db_Model_Formula_Context $context
|
34 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
35 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
36 |
+
*/
|
37 |
+
public function selectField($context, $formula, $expr) {
|
38 |
+
$expr
|
39 |
+
->setIsFrontend(true)
|
40 |
+
->setExpr("'{{= {$formula->__toString()} }}'")
|
41 |
+
->setType('varchar(255');
|
42 |
+
}
|
43 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Entity/Normal.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Entity_Normal extends Mana_Db_Helper_Formula_Entity {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
16 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
17 |
+
*/
|
18 |
+
public function selectField(/** @noinspection PhpUnusedParameterInspection */$context, $formula, $expr) {
|
19 |
+
foreach($context->getSelect()->getPart(Varien_Db_Select::COLUMNS) as $column) {
|
20 |
+
if ($column[2] == $expr->getFieldName()) {
|
21 |
+
$expr->setExpr($column[1]);
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
throw new Mana_Db_Exception_Formula($this->__("Field '%s' referenced in field '%s' is not defined.", $expr->getFieldName(), $context->getField()->getName()));
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
*
|
31 |
+
* @param Mana_Db_Model_Formula_Context $context
|
32 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
33 |
+
*/
|
34 |
+
public function select($context, $entity) {
|
35 |
+
}
|
36 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Evaluator.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Evaluator extends Mana_Db_Helper_Formula_Abstract {
|
13 |
+
public function evaluateFormula($context, $field) {
|
14 |
+
throw new Exception('Not implemented');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function evaluateValue($context, $field) {
|
18 |
+
throw new Exception('Not implemented');
|
19 |
+
}
|
20 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
abstract class Mana_Db_Helper_Formula_Function extends Mage_Core_Helper_Abstract {
|
13 |
+
protected $_name;
|
14 |
+
/**
|
15 |
+
* @param Mana_Db_Model_Formula_Context $context
|
16 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
17 |
+
* @return Mana_Db_Model_Formula_Expr
|
18 |
+
*/
|
19 |
+
abstract public function select($context, $args);
|
20 |
+
|
21 |
+
public function getName() {
|
22 |
+
if (!$this->_name) {
|
23 |
+
$class = substr(get_class($this), strlen(__CLASS__ . '_'));
|
24 |
+
$this->_name = strtoupper(preg_replace('/(.)([A-Z])/', "$1_$2", $class));
|
25 |
+
}
|
26 |
+
return $this->_name;
|
27 |
+
}
|
28 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function/Count.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Function_Count extends Mana_Db_Helper_Formula_Function {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
16 |
+
* @throws Mana_Db_Exception_Formula
|
17 |
+
* @return Mana_Db_Model_Formula_Expr
|
18 |
+
*/
|
19 |
+
public function select($context, $args) {
|
20 |
+
if (count($args) != 1) {
|
21 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects one parameter", $this->getName()));
|
22 |
+
}
|
23 |
+
if (!$args[0]->getIsAggregate()) {
|
24 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects 1 parameter to be a field of aggregate entity", $this->getName()));
|
25 |
+
}
|
26 |
+
|
27 |
+
$helper = $context->getHelper();
|
28 |
+
|
29 |
+
if ($args[0]->getSubSelect()) {
|
30 |
+
$expr = "COUNT({$args[0]->getFieldExpr()})";
|
31 |
+
|
32 |
+
return $helper->expr()->setExpr("({$args[0]->getSubSelect()->columns($expr)})")->setType('int');
|
33 |
+
}
|
34 |
+
else {
|
35 |
+
$expr = '';
|
36 |
+
$fieldExpr = $args[0]->getFieldExpr();
|
37 |
+
foreach ($fieldExpr as $field) {
|
38 |
+
if ($expr) {
|
39 |
+
$expr .= " + ";
|
40 |
+
}
|
41 |
+
$expr .= "IF ($field IS NULL, 0, 1)";
|
42 |
+
}
|
43 |
+
|
44 |
+
return $helper->expr()->setExpr($expr)->setType('int');
|
45 |
+
}
|
46 |
+
}
|
47 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function/Glue.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Function_Glue extends Mana_Db_Helper_Formula_Function {
|
13 |
+
protected $_separator = '{~#';
|
14 |
+
/**
|
15 |
+
* @param Mana_Db_Model_Formula_Context $context
|
16 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
17 |
+
* @throws Mana_Db_Exception_Formula
|
18 |
+
* @return Mana_Db_Model_Formula_Expr
|
19 |
+
*/
|
20 |
+
public function select($context, $args) {
|
21 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
22 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
23 |
+
|
24 |
+
if (count($args) < 2 || count($args) > 3) {
|
25 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects 2 or 3 parameters", $this->getName()));
|
26 |
+
}
|
27 |
+
if (!$args[0]->getIsAggregate()) {
|
28 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects 1 parameter to be a field of aggregate entity", $this->getName()));
|
29 |
+
}
|
30 |
+
|
31 |
+
$helper = $context->getHelper();
|
32 |
+
|
33 |
+
$sep = $helper->cast($args[1], 'varchar (255)')->getExpr();
|
34 |
+
$lastSep = count($args) == 3 ? $helper->cast($args[2], 'varchar (255)')->getExpr() : '';
|
35 |
+
if ($args[0]->getSubSelect()) {
|
36 |
+
$field = $helper->cast($args[0], 'varchar (255)')->getFieldExpr();
|
37 |
+
if (count($args) == 3) {
|
38 |
+
$expr =
|
39 |
+
"IF (COUNT({$args[0]->getFieldExpr()}) > 1, ".
|
40 |
+
"REPLACE(CONCAT(".
|
41 |
+
"SUBSTRING_INDEX(GROUP_CONCAT({$field} SEPARATOR '{$this->_separator}'), ".
|
42 |
+
"'{$this->_separator}', COUNT({$field}) - 1), ".
|
43 |
+
"$lastSep, ".
|
44 |
+
"SUBSTRING_INDEX(GROUP_CONCAT({$field} SEPARATOR '{$this->_separator}'), ".
|
45 |
+
"'{$this->_separator}', -1)".
|
46 |
+
"), '{$this->_separator}', $sep), ".
|
47 |
+
"GROUP_CONCAT({$field} SEPARATOR $sep)".
|
48 |
+
")";
|
49 |
+
}
|
50 |
+
else {
|
51 |
+
$expr = "GROUP_CONCAT({$field} SEPARATOR $sep)";
|
52 |
+
}
|
53 |
+
|
54 |
+
return $helper->expr()->setExpr("({$args[0]->getSubSelect()->columns($expr)})")->setType('varchar(255)');
|
55 |
+
}
|
56 |
+
else {
|
57 |
+
$expr = '';
|
58 |
+
$fieldExpr = $args[0]->getFieldExpr();
|
59 |
+
foreach ($fieldExpr as $index => $field) {
|
60 |
+
$nextField = isset($fieldExpr[$index + 1]) ? $fieldExpr[$index + 1] : '';
|
61 |
+
if ($expr) {
|
62 |
+
if (count($args) == 3) {
|
63 |
+
if ($nextField) {
|
64 |
+
$expr .= ", IF ($field IS NULL, '', CONCAT(IF ($nextField IS NULL, $lastSep, $sep), $field))";
|
65 |
+
}
|
66 |
+
else {
|
67 |
+
$expr .= ", IF ($field IS NULL, '', CONCAT($lastSep, $field))";
|
68 |
+
}
|
69 |
+
}
|
70 |
+
else {
|
71 |
+
$expr .= ", IF ($field IS NULL, '', CONCAT($sep, $field))";
|
72 |
+
}
|
73 |
+
}
|
74 |
+
else {
|
75 |
+
$expr .= "COALESCE({$helper->cast($args[0]->setExpr($field), 'varchar (255)')->getExpr()}, '')";
|
76 |
+
}
|
77 |
+
}
|
78 |
+
$expr = "CONCAT($expr)";
|
79 |
+
|
80 |
+
return $helper->expr()->setExpr($expr)->setType('varchar(255)');
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function/If.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Function_If extends Mana_Db_Helper_Formula_Function {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
16 |
+
* @throws Mana_Db_Exception_Formula
|
17 |
+
* @throws Exception
|
18 |
+
* @return Mana_Db_Model_Formula_Expr
|
19 |
+
*/
|
20 |
+
public function select($context, $args) {
|
21 |
+
if (count($args) != 3) {
|
22 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects three parameters", $this->getName()));
|
23 |
+
}
|
24 |
+
if ($args[0]->getIsAggregate()) {
|
25 |
+
throw new Mana_Db_Exception_Formula($this->__("You can only use aggregate function on aggregate fields"));
|
26 |
+
}
|
27 |
+
|
28 |
+
/* @var $helper Mana_Db_Helper_Formula_Selector */
|
29 |
+
$helper = $context->getHelper();
|
30 |
+
|
31 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
32 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
33 |
+
|
34 |
+
$condition = $args[0]->getExpr();
|
35 |
+
switch ($formulaHelper->getType($args[0]->getType())) {
|
36 |
+
case 'string':
|
37 |
+
$condition .= "<> ''";
|
38 |
+
break;
|
39 |
+
case 'int':
|
40 |
+
$condition .= "<> 0";
|
41 |
+
break;
|
42 |
+
case 'bool':
|
43 |
+
break;
|
44 |
+
default:
|
45 |
+
throw new Exception('Not implemented');
|
46 |
+
}
|
47 |
+
|
48 |
+
$helper->binaryCast($args[1], $args[2]);
|
49 |
+
return $helper->expr()->setExpr("IF({$condition}, {$args[1]->getExpr()}, {$args[2]->getExpr()})")->setType($args[1]->getType());
|
50 |
+
}
|
51 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function/Lower.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Function_Lower extends Mana_Db_Helper_Formula_Function {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
16 |
+
* @throws Mana_Db_Exception_Formula
|
17 |
+
* @return Mana_Db_Model_Formula_Expr
|
18 |
+
*/
|
19 |
+
public function select($context, $args) {
|
20 |
+
if (count($args) != 1) {
|
21 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects one parameter", $this->getName()));
|
22 |
+
}
|
23 |
+
if ($args[0]->getIsAggregate()) {
|
24 |
+
throw new Mana_Db_Exception_Formula($this->__("You can only use aggregate function on aggregate fields"));
|
25 |
+
}
|
26 |
+
|
27 |
+
$helper = $context->getHelper();
|
28 |
+
return $helper->expr()->setExpr("LOWER({$helper->cast($args[0], 'varchar(255)')->getExpr()})")->setType('varchar(255)');
|
29 |
+
}
|
30 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function/Seo.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Function_Seo extends Mana_Db_Helper_Formula_Function {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
16 |
+
* @throws Mana_Db_Exception_Formula
|
17 |
+
* @return Mana_Db_Model_Formula_Expr
|
18 |
+
*/
|
19 |
+
public function select($context, $args) {
|
20 |
+
if (count($args) != 1) {
|
21 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects one parameter", $this->getName()));
|
22 |
+
}
|
23 |
+
if ($args[0]->getIsAggregate()) {
|
24 |
+
throw new Mana_Db_Exception_Formula($this->__("You can only use aggregate function on aggregate fields"));
|
25 |
+
}
|
26 |
+
|
27 |
+
$helper = $context->getHelper();
|
28 |
+
/* @var $seo Mana_Core_Helper_Seo */
|
29 |
+
$seo = Mage::helper('mana_core/seo');
|
30 |
+
|
31 |
+
return $helper->expr()->setExpr("{$seo->select("LOWER({$helper->cast($args[0], 'varchar(255)')->getExpr()})")}")->setType('varchar(255)');
|
32 |
+
}
|
33 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Function/SkinUrl.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Function_SkinUrl extends Mana_Db_Helper_Formula_Function {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param Mana_Db_Model_Formula_Expr[] $args
|
16 |
+
* @throws Mana_Db_Exception_Formula
|
17 |
+
* @return Mana_Db_Model_Formula_Expr
|
18 |
+
*/
|
19 |
+
public function select($context, $args) {
|
20 |
+
if (count($args) != 1) {
|
21 |
+
throw new Mana_Db_Exception_Formula($this->__("Function '%s' expects one parameter", $this->getName()));
|
22 |
+
}
|
23 |
+
if ($args[0]->getIsAggregate()) {
|
24 |
+
throw new Mana_Db_Exception_Formula($this->__("You can only use aggregate function on aggregate fields"));
|
25 |
+
}
|
26 |
+
|
27 |
+
$helper = $context->getHelper();
|
28 |
+
|
29 |
+
$urlConstant = str_replace('\'', '\\\'', substr($args[0]->getExpr(), 1, strlen($args[0]->getExpr())));
|
30 |
+
return $helper->expr()->setExpr("'{{= {$this->getName()}(\\'$urlConstant\\')'")->setType('varchar(255)');
|
31 |
+
}
|
32 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Parser.php
ADDED
@@ -0,0 +1,379 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
* Language symbols:
|
12 |
+
*
|
13 |
+
* STRING ::= { ANY - '{{=' }
|
14 |
+
* Language syntax:
|
15 |
+
*
|
16 |
+
* Text ::= { Formula | String } // no spaces
|
17 |
+
* String ::= { ANY } until '{{=' | EOF )
|
18 |
+
* Formula ::= '{{=' Expr '}}' // spaces separate tokens
|
19 |
+
* Expr ::= AddExpr
|
20 |
+
* AddExpr ::= MulExpr ('+' | '-') Expr
|
21 |
+
* MulExpr ::= PrimaryExpr ('*' | '/') Expr
|
22 |
+
* PrimaryExpr ::= Function | Field | String | Number | '(' Expr ')'
|
23 |
+
* Function ::= identifier '(' { Expr ',' } ')'
|
24 |
+
* Field ::= [ identifier '.' ] identifier
|
25 |
+
*/
|
26 |
+
class Mana_Db_Helper_Formula_Parser extends Mage_Core_Helper_Abstract {
|
27 |
+
const OPEN_PAR = 1;
|
28 |
+
const CLOSE_PAR = 2;
|
29 |
+
const OPEN_FORMULA = 3;
|
30 |
+
const CLOSE_FORMULA = 4;
|
31 |
+
const IDENTIFIER = 5;
|
32 |
+
const DOT = 6;
|
33 |
+
const NUMBER = 7;
|
34 |
+
const STRING = 8;
|
35 |
+
const COMMA = 9;
|
36 |
+
const MULTIPLY = 10;
|
37 |
+
const DIVIDE = 11;
|
38 |
+
const ADD = 12;
|
39 |
+
const SUBTRACT = 13;
|
40 |
+
const EOF = 14;
|
41 |
+
|
42 |
+
static $_tokens = array(
|
43 |
+
self::OPEN_PAR => '(',
|
44 |
+
self::CLOSE_PAR => ')',
|
45 |
+
self::OPEN_FORMULA => '{{=',
|
46 |
+
self::CLOSE_FORMULA => '}}',
|
47 |
+
self::DOT => '.',
|
48 |
+
self::COMMA => ',',
|
49 |
+
self::MULTIPLY => '*',
|
50 |
+
self::DIVIDE => '/',
|
51 |
+
self::ADD => '+',
|
52 |
+
self::SUBTRACT => '-',
|
53 |
+
);
|
54 |
+
static $_multiplicationOperators = array(self::MULTIPLY, self::DIVIDE);
|
55 |
+
static $_additionOperators = array(self::ADD, self::SUBTRACT);
|
56 |
+
|
57 |
+
static $_numeric = '0123456789';
|
58 |
+
static $_firstIdentifierSymbol = '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
59 |
+
static $_nextIdentifierSymbol = '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
60 |
+
static $_whitespace = " \t\r\n";
|
61 |
+
protected $_formula;
|
62 |
+
protected $_pos;
|
63 |
+
protected $_token;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @param string $formula
|
67 |
+
* @return Mana_Db_Model_Formula_Node
|
68 |
+
*/
|
69 |
+
public function parse($formula) {
|
70 |
+
$parts = array();
|
71 |
+
$fromPos = 0;
|
72 |
+
for ($pos = strpos($formula, self::$_tokens[self::OPEN_FORMULA]); $pos !== false;
|
73 |
+
$pos = strpos($formula, self::$_tokens[self::OPEN_FORMULA], $fromPos))
|
74 |
+
{
|
75 |
+
if ($fromPos < $pos) {
|
76 |
+
$parts[] = $this->_parseString(substr($formula, $fromPos, $pos - $fromPos));
|
77 |
+
}
|
78 |
+
if (($fromPos = strpos($formula, self::$_tokens[self::CLOSE_FORMULA], $pos + strlen(self::$_tokens[self::OPEN_FORMULA]))) !== false) {
|
79 |
+
$parts[] = $this->parseFormula(substr($formula, $pos + strlen(self::$_tokens[self::OPEN_FORMULA]), $fromPos - ($pos + 3)));
|
80 |
+
$fromPos += strlen(self::$_tokens[self::CLOSE_FORMULA]);
|
81 |
+
}
|
82 |
+
else {
|
83 |
+
$this->_error(self::CLOSE_FORMULA);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
if ($fromPos < strlen($formula)) {
|
87 |
+
$parts[] = $this->_parseString(substr($formula, $fromPos));
|
88 |
+
}
|
89 |
+
if (!count($parts)) {
|
90 |
+
$parts[] = $this->_parseNull();
|
91 |
+
}
|
92 |
+
|
93 |
+
if (count($parts) > 1) {
|
94 |
+
return new Mana_Db_Model_Formula_Node_FormulaExpr(compact('parts'));
|
95 |
+
}
|
96 |
+
else {
|
97 |
+
return $parts[0];
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
protected function _parseString($value) {
|
102 |
+
return new Mana_Db_Model_Formula_Node_StringConstant(compact('value'));
|
103 |
+
}
|
104 |
+
|
105 |
+
public function parseFormula($formula) {
|
106 |
+
$this->_formula = $formula;
|
107 |
+
$this->_pos = 0;
|
108 |
+
$this->_scan();
|
109 |
+
|
110 |
+
return $this->_parseExpr();
|
111 |
+
}
|
112 |
+
|
113 |
+
protected function _parseNull() {
|
114 |
+
return new Mana_Db_Model_Formula_Node_NullValue();
|
115 |
+
}
|
116 |
+
|
117 |
+
protected function _parseExpr() {
|
118 |
+
return $this->_parseAddExpr();
|
119 |
+
}
|
120 |
+
|
121 |
+
protected function _parseAddExpr() {
|
122 |
+
$a = $this->_parseMulExpr();
|
123 |
+
$operator = $this->_token->kind;
|
124 |
+
|
125 |
+
if (in_array($operator, self::$_additionOperators)) {
|
126 |
+
$this->_scan();
|
127 |
+
$b = $this->_parseExpr();
|
128 |
+
return new Mana_Db_Model_Formula_Node_Add(compact('operator', 'a', 'b'));
|
129 |
+
}
|
130 |
+
else {
|
131 |
+
return $a;
|
132 |
+
}
|
133 |
+
|
134 |
+
}
|
135 |
+
|
136 |
+
protected function _parseMulExpr() {
|
137 |
+
$a = $this->_parsePrimaryExpr();
|
138 |
+
$operator = $this->_token->kind;
|
139 |
+
|
140 |
+
if (in_array($operator, self::$_multiplicationOperators)) {
|
141 |
+
$this->_scan();
|
142 |
+
$b = $this->_parseExpr();
|
143 |
+
return new Mana_Db_Model_Formula_Node_Multiply(compact('operator', 'a', 'b'));
|
144 |
+
}
|
145 |
+
else {
|
146 |
+
return $a;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
protected function _parsePrimaryExpr() {
|
151 |
+
if ($this->_token->kind == self::OPEN_PAR) {
|
152 |
+
$this->_scan();
|
153 |
+
$result = $this->_parseExpr();
|
154 |
+
$this->_expect(self::CLOSE_PAR);
|
155 |
+
return $result;
|
156 |
+
}
|
157 |
+
elseif ($this->_token->kind == self::STRING) {
|
158 |
+
$result = new Mana_Db_Model_Formula_Node_StringConstant(array('value' => $this->_token->text));
|
159 |
+
$this->_scan();
|
160 |
+
return $result;
|
161 |
+
}
|
162 |
+
elseif ($this->_token->kind == self::NUMBER) {
|
163 |
+
$result = new Mana_Db_Model_Formula_Node_NumberConstant(array('value' => $this->_token->text));
|
164 |
+
$this->_scan();
|
165 |
+
return $result;
|
166 |
+
}
|
167 |
+
elseif ($this->_token->kind == self::IDENTIFIER) {
|
168 |
+
$identifier = $this->_token->text;
|
169 |
+
$this->_scan();
|
170 |
+
if ($this->_token->kind == self::DOT) {
|
171 |
+
return $this->_parseField($identifier);
|
172 |
+
}
|
173 |
+
elseif ($this->_token->kind == self::OPEN_PAR) {
|
174 |
+
return $this->_parseFunction($identifier);
|
175 |
+
}
|
176 |
+
else {
|
177 |
+
return new Mana_Db_Model_Formula_Node_Identifier(compact('identifier'));
|
178 |
+
}
|
179 |
+
}
|
180 |
+
else {
|
181 |
+
$this->_error(Mage::helper('mana_db')->__('Invalid expression'));
|
182 |
+
return false;
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
protected function _parseField($identifier) {
|
187 |
+
$identifiers = array($identifier);
|
188 |
+
|
189 |
+
while ($this->_token->kind == self::DOT) {
|
190 |
+
$this->_scan();
|
191 |
+
$identifiers[] = $this->_token->text;
|
192 |
+
$this->_expect(self::IDENTIFIER);
|
193 |
+
}
|
194 |
+
|
195 |
+
return new Mana_Db_Model_Formula_Node_Field(compact('identifiers'));
|
196 |
+
}
|
197 |
+
|
198 |
+
protected function _parseFunction($name) {
|
199 |
+
$args = array();
|
200 |
+
|
201 |
+
$this->_expect(self::OPEN_PAR);
|
202 |
+
|
203 |
+
if ($this->_token->kind != self::CLOSE_PAR) {
|
204 |
+
$args[] = $this->_parseExpr();
|
205 |
+
while ($this->_token->kind == self::COMMA) {
|
206 |
+
$this->_scan();
|
207 |
+
$args[] = $this->_parseExpr();
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
$this->_expect(self::CLOSE_PAR);
|
212 |
+
|
213 |
+
return new Mana_Db_Model_Formula_Node_FunctionCall(compact('name', 'args'));
|
214 |
+
}
|
215 |
+
|
216 |
+
protected function _expect($tokenKind) {
|
217 |
+
if ($this->_token->kind != $tokenKind) {
|
218 |
+
$this->_error($tokenKind);
|
219 |
+
}
|
220 |
+
$this->_scan();
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* @param $errNo
|
225 |
+
* @throws Mana_Db_Exception_Formula
|
226 |
+
*/
|
227 |
+
protected function _error($errNo) {
|
228 |
+
if (is_string($errNo)) {
|
229 |
+
$err = $errNo;
|
230 |
+
}
|
231 |
+
else {
|
232 |
+
$t = Mage::helper('mana_db');
|
233 |
+
switch ($errNo) {
|
234 |
+
case self::IDENTIFIER: $err = $t->__("Identifier expected"); break;
|
235 |
+
case self::NUMBER: $err = $t->__("Number constant expected"); break;
|
236 |
+
case self::STRING: $err = $t->__("String constant expected"); break;
|
237 |
+
case self::EOF: $err = $t->__("End of formula expected"); break;
|
238 |
+
default:
|
239 |
+
if (isset(self::$_tokens[$errNo])) {
|
240 |
+
$err = $t->__("'%s' expected", self::$_tokens[$errNo]);
|
241 |
+
}
|
242 |
+
else {
|
243 |
+
$err = $t->__("Syntax error");
|
244 |
+
}
|
245 |
+
break;
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
throw new Mana_Db_Exception_Formula($err);
|
250 |
+
}
|
251 |
+
|
252 |
+
protected function _scan() {
|
253 |
+
$this->_token = $this->_peek(1);
|
254 |
+
$this->_pos = $this->_token->pos + $this->_token->length;
|
255 |
+
}
|
256 |
+
|
257 |
+
protected function _peek($count = 1) {
|
258 |
+
$token = null;
|
259 |
+
for ($pos = $this->_pos, $i = 0; $i < $count; $i++) {
|
260 |
+
$token = $this->_internalScan($pos);
|
261 |
+
$pos = $token->pos + $token->length;
|
262 |
+
}
|
263 |
+
return $token;
|
264 |
+
}
|
265 |
+
|
266 |
+
protected function _internalScan($pos = false) {
|
267 |
+
$kind = 0;
|
268 |
+
$text = '';
|
269 |
+
$formulaLength = strlen($this->_formula);
|
270 |
+
$state = 0;
|
271 |
+
$unexpectedEof = false;
|
272 |
+
$found = false;
|
273 |
+
|
274 |
+
if ($pos === false) {
|
275 |
+
$pos = $this->_pos;
|
276 |
+
}
|
277 |
+
$whitespacePos = $pos;
|
278 |
+
while ($pos < $formulaLength) {
|
279 |
+
$ch = substr($this->_formula, $whitespacePos++, 1);
|
280 |
+
if (strpos(self::$_whitespace, $ch) !== false) {
|
281 |
+
$pos++;
|
282 |
+
}
|
283 |
+
else {
|
284 |
+
break;
|
285 |
+
}
|
286 |
+
}
|
287 |
+
$newPos = $pos;
|
288 |
+
|
289 |
+
while (!$found) {
|
290 |
+
if ($newPos < $formulaLength) {
|
291 |
+
$ch = substr($this->_formula, $newPos++, 1);
|
292 |
+
}
|
293 |
+
elseif ($unexpectedEof) {
|
294 |
+
throw new Mana_Db_Exception_Formula(Mage::helper('mana_db')->__('Unexpected end of formula'));
|
295 |
+
}
|
296 |
+
else {
|
297 |
+
$newPos++;
|
298 |
+
if ($kind === 0) {
|
299 |
+
$kind = self::EOF;
|
300 |
+
}
|
301 |
+
break;
|
302 |
+
}
|
303 |
+
|
304 |
+
switch ($state) {
|
305 |
+
case 0: // analyzing first symbol
|
306 |
+
if ($ch == '\'') {
|
307 |
+
$kind = self::STRING;
|
308 |
+
$state = 1;
|
309 |
+
$unexpectedEof = true;
|
310 |
+
}
|
311 |
+
elseif (strpos(self::$_firstIdentifierSymbol, $ch) !== false) {
|
312 |
+
$kind = self::IDENTIFIER;
|
313 |
+
$state = 3;
|
314 |
+
}
|
315 |
+
elseif (strpos(self::$_numeric, $ch) !== false) {
|
316 |
+
$kind = self::NUMBER;
|
317 |
+
$state = 4;
|
318 |
+
}
|
319 |
+
else {
|
320 |
+
foreach (self::$_tokens as $k => $v) {
|
321 |
+
if ($k != self::OPEN_FORMULA && $k != self::CLOSE_FORMULA && strpos($this->_formula, $v, $pos) === $pos) {
|
322 |
+
$kind = $k;
|
323 |
+
$text = $v;
|
324 |
+
$found = true;
|
325 |
+
$newPos++;
|
326 |
+
break;
|
327 |
+
}
|
328 |
+
}
|
329 |
+
if (!$found) {
|
330 |
+
throw new Mana_Db_Exception_Formula(Mage::helper('mana_db')->__("Unexpected character '%s'", $ch));
|
331 |
+
}
|
332 |
+
}
|
333 |
+
break;
|
334 |
+
case 1: // inside string
|
335 |
+
if ($ch == '\\') {
|
336 |
+
$state = 2;
|
337 |
+
}
|
338 |
+
elseif ($ch == '\'') {
|
339 |
+
$newPos++;
|
340 |
+
$found = true;
|
341 |
+
}
|
342 |
+
else {
|
343 |
+
$text .= $ch;
|
344 |
+
}
|
345 |
+
break;
|
346 |
+
case 2: // processing string escape symbol
|
347 |
+
switch ($ch) {
|
348 |
+
case '\'':
|
349 |
+
case '\\':
|
350 |
+
$text .= $ch;
|
351 |
+
break;
|
352 |
+
default:
|
353 |
+
$text .= '\\';
|
354 |
+
break;
|
355 |
+
}
|
356 |
+
$state = 1;
|
357 |
+
break;
|
358 |
+
case 3: // reading identifier
|
359 |
+
if (strpos(self::$_nextIdentifierSymbol, $ch) === false) {
|
360 |
+
$found = true;
|
361 |
+
}
|
362 |
+
break;
|
363 |
+
case 4: // reading number
|
364 |
+
if (strpos(self::$_numeric, $ch) === false) {
|
365 |
+
$found = true;
|
366 |
+
}
|
367 |
+
break;
|
368 |
+
}
|
369 |
+
}
|
370 |
+
|
371 |
+
$length = $newPos - $pos - 1;
|
372 |
+
|
373 |
+
if (!$text && $length) {
|
374 |
+
$text = substr($this->_formula, $pos, $length);
|
375 |
+
}
|
376 |
+
return (object)compact('kind', 'text', 'pos', 'length');
|
377 |
+
}
|
378 |
+
|
379 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Processor.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
abstract class Mana_Db_Helper_Formula_Processor extends Mage_Core_Helper_Abstract {
|
13 |
+
protected static $_eavEntityTypes = array();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param Mana_Db_Model_Formula_Context $context
|
17 |
+
* @param string $field
|
18 |
+
* @return Mana_Db_Model_Formula_Expr | bool
|
19 |
+
*/
|
20 |
+
public function selectField(/** @noinspection PhpUnusedParameterInspection */$context, $field) {
|
21 |
+
return false;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @param Mana_Db_Model_Formula_Context $context
|
26 |
+
* @param string $entity
|
27 |
+
* @return Mana_Db_Model_Formula_Entity | bool
|
28 |
+
*/
|
29 |
+
public function selectEntity(/** @noinspection PhpUnusedParameterInspection */$context, $entity) {
|
30 |
+
return false;
|
31 |
+
}
|
32 |
+
|
33 |
+
abstract public function getPrimaryKey($entity);
|
34 |
+
|
35 |
+
public function getProcessor($entity) {
|
36 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
37 |
+
$dbConfig = Mage::helper('mana_db/config');
|
38 |
+
|
39 |
+
if ($dbConfig->getScopeXml($entity)) {
|
40 |
+
return 'entity';
|
41 |
+
}
|
42 |
+
elseif ($this->getEavEntityType($entity)) {
|
43 |
+
return 'eav';
|
44 |
+
}
|
45 |
+
else {
|
46 |
+
return 'table';
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param string $entity
|
52 |
+
* @return Mage_Eav_Model_Entity_Type | bool
|
53 |
+
*/
|
54 |
+
public function getEavEntityType($entity) {
|
55 |
+
if (!isset(self::$_eavEntityTypes[$entity])) {
|
56 |
+
/* @var $entityType Mage_Eav_Model_Entity_Type */
|
57 |
+
$entityType = Mage::getModel('eav/entity_type');
|
58 |
+
$entityType->load($entity, 'entity_model');
|
59 |
+
self::$_eavEntityTypes[$entity] = $entityType->getId() ? $entityType : false;
|
60 |
+
}
|
61 |
+
return self::$_eavEntityTypes[$entity];
|
62 |
+
}
|
63 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Processor/Eav.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Processor_Eav extends Mana_Db_Helper_Formula_Processor {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param string $field
|
16 |
+
* @return Mana_Db_Model_Formula_Expr | bool
|
17 |
+
*/
|
18 |
+
public function selectField($context, $field) {
|
19 |
+
if ($result = parent::selectField($context, $field)) {
|
20 |
+
return $result;
|
21 |
+
}
|
22 |
+
|
23 |
+
$eavEntityType = $this->getEavEntityType($context->getEntity());
|
24 |
+
/* @var $attribute Mage_Eav_Model_Entity_Attribute */
|
25 |
+
$attribute = $eavEntityType->getAttributeCollection()->getItemByColumnValue('attribute_code', $field);
|
26 |
+
|
27 |
+
if ($attribute) {
|
28 |
+
return $context->getHelper()->expr()
|
29 |
+
->setFieldExpr($context->getAlias()->fieldExpr($context, $field))
|
30 |
+
->setFieldName($field)
|
31 |
+
->setType($attribute->getBackendType());
|
32 |
+
}
|
33 |
+
else {
|
34 |
+
return false;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
public function getPrimaryKey($entity) {
|
39 |
+
return 'entity_id';
|
40 |
+
}
|
41 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Processor/Entity.php
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Processor_Entity extends Mana_Db_Helper_Formula_Processor {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param string $field
|
16 |
+
* @return Mana_Db_Model_Formula_Expr | bool
|
17 |
+
*/
|
18 |
+
public function selectField($context, $field) {
|
19 |
+
if ($result = parent::selectField($context, $field)) {
|
20 |
+
return $result;
|
21 |
+
}
|
22 |
+
|
23 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
24 |
+
$dbConfig = Mage::helper('mana_db/config');
|
25 |
+
|
26 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
27 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
28 |
+
|
29 |
+
/* @var $fieldsXml Varien_Simplexml_Element */
|
30 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
31 |
+
$fieldsXml = $dbConfig->getScopeXml($context->getEntity())->fields;
|
32 |
+
|
33 |
+
if (isset($fieldsXml->$field)) {
|
34 |
+
$alias = $context->getAlias();
|
35 |
+
return $context->getHelper()->expr()
|
36 |
+
->setFieldExpr($alias->fieldExpr($context, $field))
|
37 |
+
->setFieldName($field)
|
38 |
+
->setType((string)$fieldsXml->$field->type);
|
39 |
+
}
|
40 |
+
else {
|
41 |
+
return false;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param Mana_Db_Model_Formula_Context $context
|
47 |
+
* @param string $entity
|
48 |
+
* @return Mana_Db_Model_Formula_Entity | bool
|
49 |
+
*/
|
50 |
+
public function selectEntity($context, $entity) {
|
51 |
+
if ($aggregateContext = parent::selectEntity($context, $entity)) {
|
52 |
+
return $aggregateContext;
|
53 |
+
}
|
54 |
+
|
55 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
56 |
+
$dbConfig = Mage::helper('mana_db/config');
|
57 |
+
|
58 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
59 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
60 |
+
|
61 |
+
$scopeXml = $dbConfig->getScopeXml($context->getEntity());
|
62 |
+
if ($result = $this->_selectEntityBasedOnXml($context, $scopeXml->formula->base->from, $entity, 'foreign')) {
|
63 |
+
$this->setForeignJoin($context, $result);
|
64 |
+
return $result;
|
65 |
+
}
|
66 |
+
if ($result = $this->_selectEntityBasedOnXml($context, $scopeXml->formula->base->join, $entity, 'foreign')) {
|
67 |
+
$this->setForeignJoin($context, $result);
|
68 |
+
return $result;
|
69 |
+
}
|
70 |
+
if ($result = $this->_selectEntityBasedOnXml($context, $scopeXml->formula->aggregate, $entity, 'aggregate')) {
|
71 |
+
return $result;
|
72 |
+
}
|
73 |
+
if ($result = $this->_selectEntityBasedOnXml($context, $scopeXml->formula->frontend, $entity, 'frontend')) {
|
74 |
+
return $result;
|
75 |
+
}
|
76 |
+
$field = $entity.'_id_0';
|
77 |
+
if (isset($scopeXml->fields->$field)) {
|
78 |
+
$fieldPrefix = $entity . '_id_';
|
79 |
+
/* @var $result Mana_Db_Model_Formula_Entity */
|
80 |
+
$result = Mage::getModel('mana_db/formula_entity');
|
81 |
+
|
82 |
+
$entityName = (string)$scopeXml->fields->$field->foreign->entity;
|
83 |
+
$fields = array();
|
84 |
+
|
85 |
+
$result
|
86 |
+
->setHelper('aggregate_field')
|
87 |
+
->setEntity($entityName)
|
88 |
+
->setProcessor($this->getProcessor($entityName));
|
89 |
+
|
90 |
+
/* @var $core Mana_Core_Helper_Data */
|
91 |
+
$core = Mage::helper('mana_core');
|
92 |
+
$compositeAlias = array();
|
93 |
+
|
94 |
+
/* @var $joinClosure Mana_Db_Model_Formula_Closure_AggregateFieldJoin */
|
95 |
+
$joinClosure = Mage::getModel('mana_db/formula_closure_aggregateFieldJoin', compact('context', 'result'));
|
96 |
+
|
97 |
+
foreach ($scopeXml->fields->children() as $fieldName => $fieldXml) {
|
98 |
+
if ($core->startsWith($fieldName, $fieldPrefix)) {
|
99 |
+
$index = (int)substr($fieldName, strlen($fieldPrefix));
|
100 |
+
$context->getAlias()->child($formulaHelper->createAlias($entity . $index))->each($joinClosure
|
101 |
+
->setTargetIndex($index)
|
102 |
+
->setEntityName($entityName)
|
103 |
+
->setFieldXml($fieldXml));
|
104 |
+
}
|
105 |
+
}
|
106 |
+
$compositeAlias = $joinClosure->getCompositeAlias();
|
107 |
+
$fields = $joinClosure->getFields();
|
108 |
+
ksort($compositeAlias);
|
109 |
+
ksort($fields);
|
110 |
+
|
111 |
+
return $result
|
112 |
+
->setAlias($formulaHelper->createAlias($compositeAlias))
|
113 |
+
->setAggregateFields($fields);
|
114 |
+
}
|
115 |
+
|
116 |
+
return false;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* @param Mana_Db_Model_Formula_Context $context
|
121 |
+
* @param Mana_Db_Model_Formula_Entity $entity
|
122 |
+
*/
|
123 |
+
protected function setForeignJoin($context, $entity) {
|
124 |
+
/* @var $joinClosure Mana_Db_Model_Formula_Closure_ForeignJoin */
|
125 |
+
$joinClosure = Mage::getModel('mana_db/formula_closure_foreignJoin', compact('context', 'entity'));
|
126 |
+
$entity->setForeignJoin($context->getAlias()->each($joinClosure));
|
127 |
+
}
|
128 |
+
|
129 |
+
public function getPrimaryKey($entity) {
|
130 |
+
return 'id';
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* @param Mana_Db_Model_Formula_Context $context
|
135 |
+
* @param Varien_Simplexml_Element $xml
|
136 |
+
* @param string $entity
|
137 |
+
* @param string $mode
|
138 |
+
* @return Mana_Db_Model_Formula_Entity
|
139 |
+
*/
|
140 |
+
protected function _selectEntityBasedOnXml($context, $xml, $entity, $mode) {
|
141 |
+
if (isset($xml->$entity)) {
|
142 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
143 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
144 |
+
|
145 |
+
/* @var $entityXml Varien_Simplexml_Element */
|
146 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
147 |
+
$entityXml = $xml->$entity;
|
148 |
+
|
149 |
+
/* @var $result Mana_Db_Model_Formula_Entity */
|
150 |
+
$result = Mage::getModel('mana_db/formula_entity');
|
151 |
+
|
152 |
+
if ($entity == 'primary') {
|
153 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
154 |
+
$dbConfig = Mage::helper('mana_db/config');
|
155 |
+
|
156 |
+
$scopeXml = $dbConfig->getScopeXml($context->getEntity());
|
157 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
158 |
+
$entityName = (string)$scopeXml->flattens;
|
159 |
+
}
|
160 |
+
else {
|
161 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
162 |
+
$entityName = (string)$entityXml->entity;
|
163 |
+
}
|
164 |
+
$data = $entityXml->asArray();
|
165 |
+
$alias = $context->getAlias()->child($formulaHelper->createAlias($entity));
|
166 |
+
|
167 |
+
return $result
|
168 |
+
->setHelper($mode)
|
169 |
+
->setAlias($alias)
|
170 |
+
->setEntity($entityName)
|
171 |
+
->setProcessor($this->getProcessor($entityName))
|
172 |
+
->addData($data ? $data : array());
|
173 |
+
}
|
174 |
+
else {
|
175 |
+
return false;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Processor/System.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Processor_System extends Mana_Db_Helper_Formula_Processor {
|
13 |
+
public function getPrimaryKey($entity) {
|
14 |
+
return '';
|
15 |
+
}
|
16 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Processor/Table.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Processor_Table extends Mana_Db_Helper_Formula_Processor {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Context $context
|
15 |
+
* @param string $field
|
16 |
+
* @return Mana_Db_Model_Formula_Expr | bool
|
17 |
+
*/
|
18 |
+
public function selectField($context, $field) {
|
19 |
+
if ($result = parent::selectField($context, $field)) {
|
20 |
+
return $result;
|
21 |
+
}
|
22 |
+
|
23 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
24 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
25 |
+
|
26 |
+
$fields = $resource->getTableFields($context->getEntity());
|
27 |
+
|
28 |
+
if (isset($fields[$field])) {
|
29 |
+
return $context->getHelper()->expr()
|
30 |
+
->setFieldExpr($context->getAlias()->fieldExpr($context, $field))
|
31 |
+
->setFieldName($field)
|
32 |
+
->setType($fields[$field]['DATA_TYPE']);
|
33 |
+
}
|
34 |
+
else {
|
35 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
36 |
+
$dbConfig = Mage::helper('mana_db/config');
|
37 |
+
|
38 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
39 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
40 |
+
|
41 |
+
/* @var $fieldsXml Varien_Simplexml_Element */
|
42 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
43 |
+
$fieldsXml = $dbConfig->getTableXml($context->getEntity())->fields;
|
44 |
+
|
45 |
+
if (isset($fieldsXml->$field)) {
|
46 |
+
$alias = $context->getAlias();
|
47 |
+
$formula = $fieldsXml->$field->formula;
|
48 |
+
$context->resetLocalAliases();
|
49 |
+
|
50 |
+
if (isset($formula->join)) {
|
51 |
+
/* @var $joinContainerXml Varien_Simplexml_Element */
|
52 |
+
$joinContainerXml = $formula->join;
|
53 |
+
foreach ($joinContainerXml->children() as $joinAlias => $definition) {
|
54 |
+
/* @var $joinClosure Mana_Db_Model_Formula_Closure_Join */
|
55 |
+
$joinClosure = Mage::getModel('mana_db/formula_closure_join', compact('context', 'definition'));
|
56 |
+
$alias
|
57 |
+
->child($formulaHelper->createAlias($joinAlias))
|
58 |
+
->each($joinClosure);
|
59 |
+
|
60 |
+
}
|
61 |
+
}
|
62 |
+
return $context->getHelper()->expr()
|
63 |
+
->setFieldExpr($alias->expr($context, (string)$formula->expr))
|
64 |
+
->setFieldName($field)
|
65 |
+
->setType((string)$fieldsXml->$field->type);
|
66 |
+
}
|
67 |
+
else {
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
public function getPrimaryKey($entity) {
|
74 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
75 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
76 |
+
|
77 |
+
foreach ($resource->getTableFields($entity) as $field) {
|
78 |
+
if (!empty($field['PRIMARY'])) {
|
79 |
+
return $field['COLUMN_NAME'];
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
return false;
|
84 |
+
}
|
85 |
+
|
86 |
+
}
|
app/code/local/Mana/Db/Helper/Formula/Selector.php
ADDED
@@ -0,0 +1,450 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Helper_Formula_Selector extends Mana_Db_Helper_Formula_Abstract {
|
13 |
+
protected $_methodPrefix = '_select';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
17 |
+
* @param string $type
|
18 |
+
* @throws Mana_Db_Exception_Formula
|
19 |
+
* @return Mana_Db_Model_Formula_Expr
|
20 |
+
*/
|
21 |
+
public function cast($expr, $type) {
|
22 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
23 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
24 |
+
|
25 |
+
$sourceType = $formulaHelper->getType($expr->getType());
|
26 |
+
$targetType = $formulaHelper->getType($type);
|
27 |
+
if ($targetType == 'string') {
|
28 |
+
if ($sourceType != 'string') {
|
29 |
+
$expr = $this->expr()->setExpr("CONCAT({$expr->getExpr()})")->setType($type);
|
30 |
+
}
|
31 |
+
}
|
32 |
+
elseif ($targetType == 'int') {
|
33 |
+
if ($sourceType != 'int') {
|
34 |
+
$expr = $this->expr()->setExpr("CAST({$expr->getExpr()} AS $type)")->setType($type);
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
return $expr;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param Mana_Db_Model_Formula_Expr $expr1
|
43 |
+
* @param Mana_Db_Model_Formula_Expr $expr2
|
44 |
+
*/
|
45 |
+
public function binaryCast(&$expr1, &$expr2) {
|
46 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
47 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
48 |
+
|
49 |
+
if ($formulaHelper->getType($expr1->getType()) == 'string' || $formulaHelper->getType($expr2->getType()) == 'string') {
|
50 |
+
$expr1 = $this->cast($expr1, 'varchar(255)');
|
51 |
+
$expr2 = $this->cast($expr2, 'varchar(255)');
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @param Mana_Db_Model_Formula_Context $context
|
57 |
+
* @param Mana_Db_Model_Formula_Node $formula
|
58 |
+
*/
|
59 |
+
public function selectFormula(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
60 |
+
$expr = $this->_select($context, $formula);
|
61 |
+
if ($expr->getIsAggregate()) {
|
62 |
+
throw new Mana_Db_Exception_Formula($this->__("Aggregate field used outside of aggregate function"));
|
63 |
+
}
|
64 |
+
$expr = $this->cast($expr, $context->getField()->getType());
|
65 |
+
$expr = $this->_getOverriddenValueExpr($context, $expr->getExpr());
|
66 |
+
$context->getSelect()->columns(array($context->getField()->getName() => new Zend_Db_Expr(
|
67 |
+
$expr)));
|
68 |
+
}
|
69 |
+
|
70 |
+
public function filterFormula(/** @noinspection PhpUnusedParameterInspection */$context, $formula, $id) {
|
71 |
+
$context->getSelect()->where($this->_select($context, $formula)->getExpr() .' = ?', $id);
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param Mana_Db_Model_Formula_Context $context
|
76 |
+
* @param Mana_Db_Model_Formula_Node $formula
|
77 |
+
* @return Mana_Db_Model_Formula_Expr
|
78 |
+
*/
|
79 |
+
protected function _select(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
80 |
+
return $this->_call(func_get_args());
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @param Mana_Db_Model_Formula_Context $context
|
85 |
+
* @param mixed $value
|
86 |
+
* @throws Exception
|
87 |
+
*/
|
88 |
+
public function selectValue($context, $value) {
|
89 |
+
$expr = $this->_getOverriddenValueExpr($context, $this->_getValue($context, $value));
|
90 |
+
$context->getSelect()->columns(array($context->getField()->getName() => new Zend_Db_Expr($expr)));
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* @param Mana_Db_Model_Formula_Context $context
|
95 |
+
* @param mixed $value
|
96 |
+
* @return string
|
97 |
+
*/
|
98 |
+
protected function _getValue($context, $value) {
|
99 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
100 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
101 |
+
|
102 |
+
if ($formulaHelper->getType($context->getField()->getType()) == 'int') {
|
103 |
+
return $value;
|
104 |
+
}
|
105 |
+
else {
|
106 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
107 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
108 |
+
|
109 |
+
return $resource->getReadConnection()->quote($value);
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @param Mana_Db_Model_Formula_Context $context
|
115 |
+
* @param mixed $value
|
116 |
+
* @return string
|
117 |
+
*/
|
118 |
+
protected function _getDefaultValue($context) {
|
119 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
120 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
121 |
+
|
122 |
+
if ($formulaHelper->getType($context->getField()->getType()) == 'int') {
|
123 |
+
return "0";
|
124 |
+
}
|
125 |
+
else {
|
126 |
+
return "''";
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @param Mana_Db_Model_Formula_Context $context
|
132 |
+
*/
|
133 |
+
public function selectDefaultValue($context) {
|
134 |
+
$expr = $this->_getOverriddenValueExpr($context, $this->_getDefaultValue($context));
|
135 |
+
$context->getSelect()->columns(array($context->getField()->getName() => new Zend_Db_Expr($expr)));
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* @param Mana_Db_Model_Formula_Context $context
|
140 |
+
* @return bool
|
141 |
+
*/
|
142 |
+
public function selectSystemField($context) {
|
143 |
+
if ($context->getField()->getRole() == Mana_Db_Helper_Config::ROLE_PRIMARY_KEY) {
|
144 |
+
return false;
|
145 |
+
}
|
146 |
+
|
147 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
148 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
149 |
+
|
150 |
+
$fieldExpr = "`{$context->registerAlias('primary')}`.`{$context->getField()->getName()}`";
|
151 |
+
if ($context->getField()->hasValue()) {
|
152 |
+
$context->getSelect()->columns(array($context->getField()->getName() => new Zend_Db_Expr(
|
153 |
+
"COALESCE($fieldExpr, {$this->_getValue($context, $context->getField()->getValue())})")));
|
154 |
+
}
|
155 |
+
else {
|
156 |
+
$context->getSelect()->columns(array(
|
157 |
+
$context->getField()->getName() => new Zend_Db_Expr(
|
158 |
+
"COALESCE($fieldExpr, {$this->_getDefaultValue($context)})")
|
159 |
+
));
|
160 |
+
}
|
161 |
+
return true;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param Mana_Db_Model_Formula_Context $context
|
166 |
+
* @param Mana_Db_Model_Formula_Node_Add $formula
|
167 |
+
* @throws Mana_Db_Exception_Formula
|
168 |
+
* @throws Exception
|
169 |
+
* @return Mana_Db_Model_Formula_Expr
|
170 |
+
*/
|
171 |
+
protected function _selectAdd($context, $formula) {
|
172 |
+
if ($context->getIsAggregate()) {
|
173 |
+
throw new Mana_Db_Exception_Formula($this->__("You can only use aggregate function on aggregate fields"));
|
174 |
+
}
|
175 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
176 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
177 |
+
|
178 |
+
$a = $this->_select($context, $formula->a);
|
179 |
+
$b = $this->_select($context, $formula->b);
|
180 |
+
$this->binaryCast($a, $b);
|
181 |
+
switch ($formula->operator) {
|
182 |
+
case Mana_Db_Model_Formula_Node_Add::ADD:
|
183 |
+
if ($formulaHelper->getType($a->getType()) == 'string') {
|
184 |
+
return $this->expr()->setExpr("CONCAT({$a->getExpr()}, {$b->getExpr()})")->setType($a->getType());
|
185 |
+
}
|
186 |
+
else {
|
187 |
+
return $this->expr()->setExpr("{$a->getExpr()} + {$b->getExpr()}")->setType($a->getType());
|
188 |
+
}
|
189 |
+
case Mana_Db_Model_Formula_Node_Add::SUBTRACT:
|
190 |
+
if ($formulaHelper->getType($a->getType()) == 'string') {
|
191 |
+
throw new Mana_Db_Exception_Formula($this->__("'%s' operator is not supported on fields of %s type", '-', 'string'));
|
192 |
+
}
|
193 |
+
else {
|
194 |
+
return $this->expr()->setExpr("{$a->getExpr()} - {$b->getExpr()}")->setType($a->getType());
|
195 |
+
}
|
196 |
+
default:
|
197 |
+
throw new Exception('Not implemented');
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Converts parsed field expression $formula into SQL column expression. If needed, introduces new joins in current
|
203 |
+
* SELECT.
|
204 |
+
*
|
205 |
+
* @param Mana_Db_Model_Formula_Context $originalContext
|
206 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
207 |
+
* @throws Mana_Db_Exception_Formula
|
208 |
+
* @return Mana_Db_Model_Formula_Expr
|
209 |
+
*
|
210 |
+
* Field expression looks like "a.b.c.d".
|
211 |
+
*
|
212 |
+
* The last identifier is field name (in case of system configuration fields field
|
213 |
+
* name consists of 3 last identifiers "b.c.d").
|
214 |
+
*
|
215 |
+
* All the identifiers before field name ("a.b.c") are entity names. Each of them is either foreign entities,
|
216 |
+
* frontend entities or aggregate entities:
|
217 |
+
* * foreign entity example: catalog/product for sales/order_item. For foreign entity LEFT or INNER JOIN is added based on
|
218 |
+
* foreign key and primary key relationship and column using that foreign key is added.
|
219 |
+
* * aggregate entity example sales/order_item for sales/order. Fields from aggregate entities are returned to
|
220 |
+
* parent formula node which is expected to be an aggregate formula such as GLUE, SUM, MAX. In final SQL aggregate
|
221 |
+
* fields appear as sub selects, so sub select object is returned for aggregate field as well.
|
222 |
+
* * frontend entity example: catalog/category for mana_attributepage/page (in database there is no relation to
|
223 |
+
* frontend entity, but it is known when calculated in frontend, typically from Mage::registry()). Such entities
|
224 |
+
* are left unprocessed (with type = 'formula,int' or 'formula,string') and are only processed before displaying
|
225 |
+
* data in frontend. Frontend entities can appear in identifier chain in first position only.
|
226 |
+
*
|
227 |
+
* How these entity types behave in identifier chain:
|
228 |
+
* * foreign entity:
|
229 |
+
* * no aggregate or frontend entity met: adds JOIN to main SELECT and changes current entity in main context
|
230 |
+
* * inside aggregate, no frontend entity met: adds JOIN to aggregate SUBSELECT and changes current entity in
|
231 |
+
* subselect context
|
232 |
+
* * inside frontend entity: changes current entity in main context
|
233 |
+
* * aggregate entity:
|
234 |
+
* * no frontend entity met: creates aggregate context to collect aggregate subselect
|
235 |
+
* * inside frontend entity: changes current entity in main context
|
236 |
+
* * frontend entity: sets a flag for processing frontend entity
|
237 |
+
*/
|
238 |
+
protected function _selectField($originalContext, $formula) {
|
239 |
+
if ($formula->identifiers[0] == 'this') {
|
240 |
+
if (count($formula->identifiers) == 1) {
|
241 |
+
throw new Mana_Db_Exception_Formula(Mage::helper('mana_db')->__("'%s' is entity, but field expected", implode('.', $formula->identifiers)));
|
242 |
+
}
|
243 |
+
$formula->identifiers = array_slice($formula->identifiers, 1);
|
244 |
+
if (count($formula->identifiers) == 1) {
|
245 |
+
/* @var $identifier Mana_Db_Model_Formula_Node_Identifier */
|
246 |
+
$identifier = Mage::getModel('mana_db/formula_node_identifier');
|
247 |
+
$identifier->identifier = $formula->identifiers[0];
|
248 |
+
$this->_selectIdentifier($originalContext, $identifier);
|
249 |
+
}
|
250 |
+
}
|
251 |
+
$context = clone $originalContext;
|
252 |
+
$result = $this->_selectFieldRecursively($context, $formula, 0);
|
253 |
+
$originalContext->copyAliases($context);
|
254 |
+
return $result;
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Converts parsed field expression $formula into SQL column expression. If needed, introduces new joins in current
|
259 |
+
* SELECT.
|
260 |
+
*
|
261 |
+
* @param Mana_Db_Model_Formula_Context $context
|
262 |
+
* @param Mana_Db_Model_Formula_Node_Field $formula
|
263 |
+
* @param int $index
|
264 |
+
* @throws Mana_Db_Exception_Formula
|
265 |
+
* @return Mana_Db_Model_Formula_Expr
|
266 |
+
*/
|
267 |
+
protected function _selectFieldRecursively($context, $formula, $index) {
|
268 |
+
$processor = $context->getProcessor();
|
269 |
+
if (isset($formula->identifiers[$index])) {
|
270 |
+
$identifier = $formula->identifiers[$index];
|
271 |
+
}
|
272 |
+
else {
|
273 |
+
throw new Mana_Db_Exception_Formula(Mage::helper('mana_db')->__("'%s' is entity, but field expected", implode('.', $formula->identifiers)));
|
274 |
+
}
|
275 |
+
|
276 |
+
if ($result = $processor->selectField($context, implode('.', array_slice($formula->identifiers, $index)))) {
|
277 |
+
$context->getEntityHelper()->selectField($context, $formula, $result);
|
278 |
+
return $result;
|
279 |
+
}
|
280 |
+
else {
|
281 |
+
if ($entity = $processor->selectEntity($context, $identifier)) {
|
282 |
+
$entity->getHelper()->select($context, $entity);
|
283 |
+
$result = $this->_selectFieldRecursively($context, $formula, ++$index);
|
284 |
+
$entity->getHelper()->endSelect($context, $entity);
|
285 |
+
return $result;
|
286 |
+
}
|
287 |
+
elseif ($index == 0) {
|
288 |
+
$context->setEntity($context->getPrimaryEntity());
|
289 |
+
return $this->_selectFieldRecursively($context, $formula, $index);
|
290 |
+
}
|
291 |
+
else {
|
292 |
+
throw new Mana_Db_Exception_Formula($this->__("Unknown field or entity '%s'", $identifier));
|
293 |
+
}
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* @param Mana_Db_Model_Formula_Context $context
|
299 |
+
* @param Mana_Db_Model_Formula_Node_FormulaExpr $formula
|
300 |
+
* @return Mana_Db_Model_Formula_Expr
|
301 |
+
*/
|
302 |
+
protected function _selectFormulaExpr($context, $formula) {
|
303 |
+
$parts = array();
|
304 |
+
foreach ($formula->parts as $part) {
|
305 |
+
$parts[] = $this->cast($this->_select($context, $part), 'varchar(255)')->getExpr();
|
306 |
+
}
|
307 |
+
$parts = implode(', ', $parts);
|
308 |
+
return $this->expr()->setExpr("CONCAT($parts)")->setType('varchar(255)');
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* @param Mana_Db_Model_Formula_Context $context
|
313 |
+
* @param Mana_Db_Model_Formula_Node_FunctionCall $formula
|
314 |
+
* @return Mana_Db_Model_Formula_Expr
|
315 |
+
*/
|
316 |
+
protected function _selectFunctionCall($context, $formula) {
|
317 |
+
$args = array();
|
318 |
+
foreach ($formula->args as $arg) {
|
319 |
+
$args[] = $this->_select($context, $arg);
|
320 |
+
}
|
321 |
+
|
322 |
+
return $this->getFunction($formula->name)->select($context, $args);
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* @param Mana_Db_Model_Formula_Context $context
|
327 |
+
* @param Mana_Db_Model_Formula_Node_Identifier $formula
|
328 |
+
* @throws Mana_Db_Exception_Formula
|
329 |
+
* @return Mana_Db_Model_Formula_Expr
|
330 |
+
*/
|
331 |
+
protected function _selectIdentifier($context, $formula) {
|
332 |
+
if ($result = $context->getProcessor()->selectField($context, $formula->identifier)) {
|
333 |
+
$context->getEntityHelper()->selectField($context, null, $result);
|
334 |
+
|
335 |
+
return $result;
|
336 |
+
}
|
337 |
+
else {
|
338 |
+
throw new Mana_Db_Exception_Formula($this->__("Can't evaluate '%s'", $formula->identifier));
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
/**
|
343 |
+
* @param Mana_Db_Model_Formula_Context $context
|
344 |
+
* @param Mana_Db_Model_Formula_Node_Multiply $formula
|
345 |
+
* @throws Mana_Db_Exception_Formula
|
346 |
+
* @throws Exception
|
347 |
+
* @return Mana_Db_Model_Formula_Expr
|
348 |
+
*/
|
349 |
+
protected function _selectMultiply($context, $formula) {
|
350 |
+
if ($context->getIsAggregate()) {
|
351 |
+
throw new Mana_Db_Exception_Formula($this->__("You can only use aggregate function on aggregate fields"));
|
352 |
+
}
|
353 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
354 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
355 |
+
|
356 |
+
$a = $this->_select($context, $formula->a);
|
357 |
+
$b = $this->_select($context, $formula->b);
|
358 |
+
$this->binaryCast($a, $b);
|
359 |
+
switch ($formula->operator) {
|
360 |
+
case Mana_Db_Model_Formula_Node_Multiply::MULTIPLY:
|
361 |
+
if ($formulaHelper->getType($a->getType()) == 'string') {
|
362 |
+
throw new Mana_Db_Exception_Formula($this->__("'%s' operator is not supported on fields of %s type", '*', 'string'));
|
363 |
+
}
|
364 |
+
else {
|
365 |
+
return $this->expr()->setExpr("{$a->getExpr()} * {$b->getExpr()}")->setType($a->getType());
|
366 |
+
}
|
367 |
+
case Mana_Db_Model_Formula_Node_Multiply::DIVIDE:
|
368 |
+
if ($formulaHelper->getType($a->getType()) == 'string') {
|
369 |
+
throw new Mana_Db_Exception_Formula($this->__("'%s' operator is not supported on fields of %s type", '/', 'string'));
|
370 |
+
}
|
371 |
+
else {
|
372 |
+
return $this->expr()->setExpr("{$a->getExpr()} / {$b->getExpr()}")->setType($a->getType());
|
373 |
+
}
|
374 |
+
default:
|
375 |
+
throw new Exception('Not implemented');
|
376 |
+
}
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* @param Mana_Db_Model_Formula_Context $context
|
381 |
+
* @param Mana_Db_Model_Formula_Node_NullValue $formula
|
382 |
+
* @return Mana_Db_Model_Formula_Expr
|
383 |
+
*/
|
384 |
+
protected function _selectNullValue(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
385 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
386 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
387 |
+
|
388 |
+
$type = $context->getField()->getType();
|
389 |
+
$formulaType = $formulaHelper->getType($type);
|
390 |
+
if ($formulaType == 'int') {
|
391 |
+
return $this->expr()->setExpr("0")->setType($type);
|
392 |
+
}
|
393 |
+
else {
|
394 |
+
return $this->expr()->setExpr("''")->setType($type);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* @param Mana_Db_Model_Formula_Context $context
|
400 |
+
* @param Mana_Db_Model_Formula_Node_NumberConstant $formula
|
401 |
+
* @return Mana_Db_Model_Formula_Expr
|
402 |
+
*/
|
403 |
+
protected function _selectNumberConstant(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
404 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
405 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
406 |
+
|
407 |
+
return $this->expr()->setExpr("{$formula->value}")->setType($formulaHelper->getMinimumNumericType($formula->value));
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* @param Mana_Db_Model_Formula_Context $context
|
412 |
+
* @param Mana_Db_Model_Formula_Node_StringConstant $formula
|
413 |
+
* @return Mana_Db_Model_Formula_Expr
|
414 |
+
*/
|
415 |
+
protected function _selectStringConstant(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
416 |
+
return $this->expr()->setExpr("'{$formula->value}'")->setType('varchar(255)');
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* @param Mana_Db_Model_Formula_Context $context
|
421 |
+
* @param Mana_Db_Model_Formula_Node $formula
|
422 |
+
*/
|
423 |
+
protected function _selectNode(/** @noinspection PhpUnusedParameterInspection */$context, $formula) {
|
424 |
+
// all future nodes ignored
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* @param Mana_Db_Model_Formula_Context $context
|
429 |
+
* @param string $defaultExpr
|
430 |
+
* @return string
|
431 |
+
*/
|
432 |
+
protected function _getOverriddenValueExpr($context, $defaultExpr) {
|
433 |
+
if (($no = $context->getField()->getNo()) !== null) {
|
434 |
+
$overriddenExpr = "`p`.`{$context->getField()->getName()}`";
|
435 |
+
if ($overriddenExpr != $defaultExpr) {
|
436 |
+
/* @var $db Mana_Db_Helper_Data */
|
437 |
+
$db = Mage::helper('mana_db');
|
438 |
+
|
439 |
+
$condition = "`p`.`default_mask{$db->getMaskIndex($no)}` & {$db->getMask($no)} = {$db->getMask($no)}";
|
440 |
+
return "IF ($condition, $overriddenExpr, $defaultExpr)";
|
441 |
+
}
|
442 |
+
else {
|
443 |
+
return $overriddenExpr;
|
444 |
+
}
|
445 |
+
}
|
446 |
+
else {
|
447 |
+
return $defaultExpr;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
}
|
app/code/local/Mana/Db/Model/Entity.php
ADDED
@@ -0,0 +1,296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getScopeName()
|
11 |
+
* @method int getEditStatus()
|
12 |
+
* @method Mana_Db_Model_Entity setEditStatus(int $value)
|
13 |
+
* @method Mana_Db_Model_Entity setEditSessionId(int $value)
|
14 |
+
* @method Mana_Db_Model_Entity setEditMassaction(int $value)
|
15 |
+
* @method string getDefaultFormulas()
|
16 |
+
* @method int getStoreId()
|
17 |
+
* @method Mana_Db_Model_Entity setStoreId(int $value)
|
18 |
+
* @method int getGlobalId()
|
19 |
+
* @method Mana_Seo_Model_Schema setGlobalId(int $value)
|
20 |
+
* @method int getPrimaryId()
|
21 |
+
* @method Mana_Seo_Model_Schema setPrimaryId(int $value)
|
22 |
+
* @method int getPrimaryGlobalId()
|
23 |
+
* @method Mana_Seo_Model_Schema setPrimaryGlobalId(int $value)
|
24 |
+
*/
|
25 |
+
class Mana_Db_Model_Entity extends Mage_Core_Model_Abstract {
|
26 |
+
protected $_scope;
|
27 |
+
protected $_isIndexingDisabled = false;
|
28 |
+
protected $_jsons;
|
29 |
+
|
30 |
+
public function __construct($data = null) {
|
31 |
+
if (is_array($data)) {
|
32 |
+
if (isset($data['scope'])) {
|
33 |
+
$this->_scope = $data['scope'];
|
34 |
+
unset($data['scope']);
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
parent::__construct($data);
|
39 |
+
}
|
40 |
+
|
41 |
+
public function loadForStore($id, $storeId, $fieldName = 'global_id') {
|
42 |
+
$this->_getResource()->loadForStore($this, $id, $storeId, $fieldName);
|
43 |
+
$this->_afterLoad();
|
44 |
+
$this->setOrigData();
|
45 |
+
$this->_hasDataChanges = false;
|
46 |
+
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
|
50 |
+
protected function _construct() {
|
51 |
+
$this->_initScope();
|
52 |
+
}
|
53 |
+
|
54 |
+
protected function _initScope() {
|
55 |
+
/* @var $db Mana_Db_Helper_Data */
|
56 |
+
$db = Mage::helper('mana_db');
|
57 |
+
|
58 |
+
$this->_init($db->getScopedName($this->_scope), 'id');
|
59 |
+
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
|
63 |
+
protected function _getResource() {
|
64 |
+
/* @var $db Mana_Db_Helper_Data */
|
65 |
+
$db = Mage::helper('mana_db');
|
66 |
+
|
67 |
+
if (empty($this->_resourceName)) {
|
68 |
+
Mage::throwException(Mage::helper('core')->__('Resource is not set.'));
|
69 |
+
}
|
70 |
+
|
71 |
+
return $db->getResourceSingleton($this->_resourceName);
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getScope() {
|
75 |
+
return $this->_scope;
|
76 |
+
}
|
77 |
+
|
78 |
+
public function assignDefaultValues() {
|
79 |
+
$this->setDummy(true);
|
80 |
+
return $this;
|
81 |
+
}
|
82 |
+
|
83 |
+
public function addGridCellData($cells) {
|
84 |
+
foreach ($cells as $column => $cell) {
|
85 |
+
$this->overrideData($column, $cell['value']);
|
86 |
+
}
|
87 |
+
return $this;
|
88 |
+
}
|
89 |
+
|
90 |
+
public function loadEdited($id, $sessionId) {
|
91 |
+
$this->_beforeLoad($id);
|
92 |
+
|
93 |
+
/* @var $resource Mana_Db_Resource_Entity */
|
94 |
+
$resource = $this->_getResource();
|
95 |
+
$resource->loadEdited($this, $id, $sessionId);
|
96 |
+
|
97 |
+
$this->_afterLoad();
|
98 |
+
$this->setOrigData();
|
99 |
+
$this->_hasDataChanges = false;
|
100 |
+
return $this;
|
101 |
+
}
|
102 |
+
|
103 |
+
public function disableIndexing() {
|
104 |
+
$this->_isIndexingDisabled = true;
|
105 |
+
return $this;
|
106 |
+
}
|
107 |
+
|
108 |
+
public function enableIndexing() {
|
109 |
+
$this->_isIndexingDisabled = false;
|
110 |
+
return $this;
|
111 |
+
}
|
112 |
+
|
113 |
+
public function updateIndexes() {
|
114 |
+
return $this;
|
115 |
+
}
|
116 |
+
|
117 |
+
public function validate($dataSource) {
|
118 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
119 |
+
$dbConfig = Mage::helper('mana_db/config');
|
120 |
+
|
121 |
+
foreach ($dbConfig->getScopeValidators($this->_scope) as $validator) {
|
122 |
+
call_user_func(array($this, $validator->getName()), $dataSource);
|
123 |
+
}
|
124 |
+
|
125 |
+
foreach ($dbConfig->getScopeFields($this->_scope) as $fieldXml) {
|
126 |
+
foreach ($dbConfig->getFieldValidators($fieldXml) as $validator) {
|
127 |
+
call_user_func(array($this, $validator->getName()), $dataSource, $fieldXml->getName());
|
128 |
+
}
|
129 |
+
}
|
130 |
+
return $this;
|
131 |
+
}
|
132 |
+
|
133 |
+
public function postValidate($dataSource) {
|
134 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
135 |
+
$dbConfig = Mage::helper('mana_db/config');
|
136 |
+
|
137 |
+
foreach ($dbConfig->getScopePostValidators($this->_scope) as $validator) {
|
138 |
+
call_user_func(array($this, $validator->getName()), $dataSource);
|
139 |
+
}
|
140 |
+
|
141 |
+
foreach ($dbConfig->getScopeFields($this->_scope) as $fieldXml) {
|
142 |
+
foreach ($dbConfig->getFieldPostValidators($fieldXml) as $validator) {
|
143 |
+
call_user_func(array($this, $validator->getName()), $dataSource, $fieldXml->getName());
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
return $this;
|
148 |
+
}
|
149 |
+
|
150 |
+
public function isNotEmpty($dataSource, $field) {
|
151 |
+
if (!$this->getData($field)) {
|
152 |
+
throw new Mana_Db_Exception_Validation(Mage::helper('mana_db')->__("Please fill in '%s'.", $dataSource->getLabel($this->getScope(), $field)));
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
public function getJson($key) {
|
157 |
+
if (!$this->_jsons) {
|
158 |
+
$this->_jsons = array();
|
159 |
+
}
|
160 |
+
if (!isset($this->_jsons[$key])) {
|
161 |
+
$data = $this->getData($key);
|
162 |
+
if (empty($data)) {
|
163 |
+
$this->_jsons[$key] = array();
|
164 |
+
}
|
165 |
+
else {
|
166 |
+
$this->_jsons[$key] = json_decode($data, true);
|
167 |
+
if (is_null($this->_jsons[$key])) {
|
168 |
+
throw new Exception(json_last_error());
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
return $this->_jsons[$key];
|
174 |
+
}
|
175 |
+
|
176 |
+
public function overrideData($key, $value = null) {
|
177 |
+
$this->setData($key, $value);
|
178 |
+
|
179 |
+
if (is_array($key)) {
|
180 |
+
foreach (array_keys($key) as $aKey) {
|
181 |
+
$this->_setDefaultMask($aKey, true);
|
182 |
+
}
|
183 |
+
}
|
184 |
+
else {
|
185 |
+
$this->_setDefaultMask($key, true);
|
186 |
+
}
|
187 |
+
return $this;
|
188 |
+
}
|
189 |
+
|
190 |
+
protected function _setDefaultMask($key, $value) {
|
191 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
192 |
+
$dbConfig = Mage::helper('mana_db/config');
|
193 |
+
|
194 |
+
if (($field = $dbConfig->getScopeField($this->_scope, $key)) && isset($field->no)) {
|
195 |
+
/* @var $db Mana_Db_Helper_Data */
|
196 |
+
$db = Mage::helper('mana_db');
|
197 |
+
|
198 |
+
$no = (int)(string)$field->no;
|
199 |
+
$maskIndex = $db->getMaskIndex($no);
|
200 |
+
$mask = isset($this->_data['default_mask' . $maskIndex]) ? $this->_data['default_mask' . $maskIndex] : 0;
|
201 |
+
if ($value) {
|
202 |
+
$mask = $mask | $db->getMask($no);
|
203 |
+
}
|
204 |
+
else {
|
205 |
+
$mask = $mask & ~$db->getMask($no);
|
206 |
+
}
|
207 |
+
$this->setData('default_mask' . $maskIndex, $mask);
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
public function useDefaultData($key) {
|
212 |
+
if (is_array($key)) {
|
213 |
+
foreach ($key as $aKey) {
|
214 |
+
$this->_setDefaultMask($aKey, false);
|
215 |
+
}
|
216 |
+
}
|
217 |
+
else {
|
218 |
+
$this->_setDefaultMask($key, false);
|
219 |
+
}
|
220 |
+
|
221 |
+
return $this;
|
222 |
+
}
|
223 |
+
|
224 |
+
public function isUsingDefaultData($key, $in = '_data') {
|
225 |
+
if (($field = $this->dbConfigHelper()->getScopeField($this->_scope, $key)) && isset($field->no)) {
|
226 |
+
/* @var $db Mana_Db_Helper_Data */
|
227 |
+
$db = Mage::helper('mana_db');
|
228 |
+
|
229 |
+
$no = (int)(string)$field->no;
|
230 |
+
$maskIndex = $db->getMaskIndex($no);
|
231 |
+
$data = $this->$in;
|
232 |
+
$mask = isset($data['default_mask' . $maskIndex]) ? $data['default_mask' . $maskIndex] : 0;
|
233 |
+
return !($mask & $db->getMask($no));
|
234 |
+
}
|
235 |
+
return false;
|
236 |
+
}
|
237 |
+
|
238 |
+
public function isDefaultable($key) {
|
239 |
+
return ($field = $this->dbConfigHelper()->getScopeField($this->_scope, $key)) && isset($field->no);
|
240 |
+
}
|
241 |
+
|
242 |
+
public function getFieldsXml() {
|
243 |
+
return $this->dbConfigHelper()->getScopeFields($this->_scope);
|
244 |
+
}
|
245 |
+
|
246 |
+
public function getDefaultableFields() {
|
247 |
+
$result = array();
|
248 |
+
foreach ($this->getFieldsXml() as $fieldXml) {
|
249 |
+
if (isset($fieldXml->no)) {
|
250 |
+
$result[] = (string)$fieldXml->name;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
return $result;
|
254 |
+
}
|
255 |
+
|
256 |
+
public function __call($method, $args) {
|
257 |
+
if (substr($method, 0, 8) == 'override') {
|
258 |
+
//Varien_Profiler::start('SETTER: '.get_class($this).'::'.$method);
|
259 |
+
$key = $this->_underscore(substr($method, 8));
|
260 |
+
$result = $this->overrideData($key, isset($args[0]) ? $args[0] : null);
|
261 |
+
|
262 |
+
//Varien_Profiler::stop('SETTER: '.get_class($this).'::'.$method);
|
263 |
+
return $result;
|
264 |
+
}
|
265 |
+
return parent::__call($method, $args);
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Init indexing process after category data commit
|
270 |
+
*
|
271 |
+
* @return Mage_Catalog_Model_Category
|
272 |
+
*/
|
273 |
+
public function afterCommitCallback() {
|
274 |
+
parent::afterCommitCallback();
|
275 |
+
if (!Mage::registry('m_prevent_indexing_on_save')) {
|
276 |
+
$this->getIndexerSingleton()->processEntityAction($this, $this->getScope(), Mage_Index_Model_Event::TYPE_SAVE);
|
277 |
+
}
|
278 |
+
return $this;
|
279 |
+
}
|
280 |
+
|
281 |
+
#region Dependencies
|
282 |
+
/**
|
283 |
+
* @return Mana_Db_Helper_Config
|
284 |
+
*/
|
285 |
+
public function dbConfigHelper() {
|
286 |
+
return Mage::helper('mana_db/config');
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* @return Mage_Index_Model_Indexer
|
291 |
+
*/
|
292 |
+
public function getIndexerSingleton() {
|
293 |
+
return Mage::getSingleton('index/indexer');
|
294 |
+
}
|
295 |
+
#endregion
|
296 |
+
}
|
app/code/local/Mana/Db/Model/Entity/Indexer.php
ADDED
@@ -0,0 +1,349 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Entity_Indexer extends Mana_Core_Model_Indexer {
|
13 |
+
protected $_code = 'mana_db';
|
14 |
+
protected $_standardEventEntities = array(
|
15 |
+
'core_store' => 'core/store',
|
16 |
+
);
|
17 |
+
/**
|
18 |
+
* @var Varien_Object[]
|
19 |
+
*/
|
20 |
+
protected $_matchedEvents = array();
|
21 |
+
|
22 |
+
public function matchEvent(Mage_Index_Model_Event $event) {
|
23 |
+
/* @var $object Mana_Db_Model_Entity */
|
24 |
+
$object = $event->getData('data_object');
|
25 |
+
$key = $event->getData('entity').'-'.$object->getId();
|
26 |
+
if (!isset($this->_matchedEvents[$key])) {
|
27 |
+
$this->_matchedEvents[$key] = $this->_matchEntity($event, $object);
|
28 |
+
}
|
29 |
+
return $this->_matchedEvents[$key]->getData('is_matching');
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param Mage_Index_Model_Event $event
|
34 |
+
* @param Mana_Db_Model_Entity $object
|
35 |
+
* @return Varien_Object
|
36 |
+
*/
|
37 |
+
protected function _matchEntity($event, /** @noinspection PhpUnusedParameterInspection */ $object) {
|
38 |
+
$result = new Varien_Object(array('is_matching' => false));
|
39 |
+
$entityFilters = array();
|
40 |
+
$eventEntity = $event->getData('entity');
|
41 |
+
if (isset($this->_standardEventEntities[$eventEntity])) {
|
42 |
+
$eventEntity = $this->_standardEventEntities[$eventEntity];
|
43 |
+
}
|
44 |
+
foreach ($this->_sortTargetsByDependency() as $target) {
|
45 |
+
if ($entity = (string)$target->entity) {
|
46 |
+
foreach ($this->dbConfigHelper()->getEntityXml($entity)->scopes->children() as $scope) {
|
47 |
+
if (isset($scope->flattens)) {
|
48 |
+
if ($formula = $this->_findEntityFilterFormula($entity . '/' . $scope->getName(), $eventEntity)) {
|
49 |
+
$result->setData('is_matching', true);
|
50 |
+
$entityFilters[$entity . '/' . $scope->getName()] = $formula;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
$result->setData('entity_filters', $entityFilters);
|
58 |
+
return $result;
|
59 |
+
}
|
60 |
+
protected function _findEntityFilterFormula($entity, $what) {
|
61 |
+
return $this->_findEntityFilterFormulaRecursively($entity, $what, '');
|
62 |
+
}
|
63 |
+
|
64 |
+
protected function _findEntityFilterFormulaRecursively($entity, $what, $formula) {
|
65 |
+
if (!($scopeXml = $this->dbConfigHelper()->getScopeXml($entity))) {
|
66 |
+
return false;
|
67 |
+
}
|
68 |
+
|
69 |
+
if (!isset($scopeXml->formula)) {
|
70 |
+
return false;
|
71 |
+
}
|
72 |
+
|
73 |
+
foreach ($scopeXml->formula->children() as $selectXml) {
|
74 |
+
if (isset($selectXml->from)) {
|
75 |
+
$fromXml = $selectXml->from;
|
76 |
+
foreach ($fromXml->children() as $alias => $definition) {
|
77 |
+
$sourceEntity = $alias == 'primary' ? (string)$scopeXml->flattens : (string)$definition->entity;
|
78 |
+
if ($sourceEntity == $what) {
|
79 |
+
return $formula . $alias . '.' . $this->_getPrimaryKey($sourceEntity);
|
80 |
+
}
|
81 |
+
else {
|
82 |
+
if ($result = $this->_findEntityFilterFormulaRecursively($sourceEntity, $what, $formula . $alias . '.')) {
|
83 |
+
return $result;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
if (isset($selectXml->join)) {
|
90 |
+
$joinXml = $selectXml->join;
|
91 |
+
/* @var $joinXml SimpleXMLElement */
|
92 |
+
foreach ($joinXml->children() as $alias => $definition) {
|
93 |
+
$sourceEntity = $alias == 'primary' ? (string)$scopeXml->flattens : (string)$definition->entity;
|
94 |
+
if ($sourceEntity == $what) {
|
95 |
+
return $formula . $alias . '.' . $this->_getPrimaryKey($sourceEntity);
|
96 |
+
}
|
97 |
+
else {
|
98 |
+
if ($result = $this->_findEntityFilterFormulaRecursively($sourceEntity, $what, $formula . $alias . '.')) {
|
99 |
+
return $result;
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
protected function _getPrimaryKey($entity) {
|
109 |
+
if ($this->dbConfigHelper()->getScopeXml($entity)) {
|
110 |
+
return 'id';
|
111 |
+
}
|
112 |
+
else {
|
113 |
+
return $this->tableProcessorHelper()->getPrimaryKey($entity);
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Register indexer required data inside event object
|
119 |
+
*
|
120 |
+
* @param Mage_Index_Model_Event $event
|
121 |
+
*/
|
122 |
+
protected function _registerEvent(Mage_Index_Model_Event $event) {
|
123 |
+
/* @var $object Mana_Db_Model_Entity */
|
124 |
+
$object = $event->getData('data_object');
|
125 |
+
$key = $event->getData('entity') . '-' . $object->getId();
|
126 |
+
if (isset($this->_matchedEvents[$key])) {
|
127 |
+
$event
|
128 |
+
->addNewData('entity_filters', $this->_matchedEvents[$key]->getData('entity_filters'))
|
129 |
+
->addNewData('entity_filter_id', $object->getId());
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Process event based on event state data
|
135 |
+
*
|
136 |
+
* @param Mage_Index_Model_Event $event
|
137 |
+
*/
|
138 |
+
protected function _processEvent(Mage_Index_Model_Event $event) {
|
139 |
+
$this->process($event->getNewData());
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @return Mana_Db_Resource_Entity_Indexer
|
144 |
+
*/
|
145 |
+
protected function _getResource() {
|
146 |
+
if (!$this->_resourceName) {
|
147 |
+
$this->_resourceName = (string)$this->getXml()->resource;
|
148 |
+
}
|
149 |
+
if (!$this->_resourceName) {
|
150 |
+
$this->_resourceName = 'mana_db/entity_indexer';
|
151 |
+
}
|
152 |
+
|
153 |
+
return Mage::getResourceSingleton($this->_resourceName);
|
154 |
+
}
|
155 |
+
|
156 |
+
public function reindexAll() {
|
157 |
+
$this->process(array(
|
158 |
+
"{$this->getCode()}_reindex_all" => true
|
159 |
+
));
|
160 |
+
|
161 |
+
return $this;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param array $options
|
166 |
+
* @return array
|
167 |
+
*/
|
168 |
+
protected function _prepareOptions($options) {
|
169 |
+
/* @var $core Mana_Core_Helper_Data */
|
170 |
+
$core = Mage::helper('mana_core');
|
171 |
+
|
172 |
+
$result = array();
|
173 |
+
foreach ($options as $key => $value) {
|
174 |
+
if ($core->startsWith($key, $this->getCode() . '_')) {
|
175 |
+
$key = substr($key, strlen($this->getCode() . '_'));
|
176 |
+
}
|
177 |
+
$result[$key] = $value;
|
178 |
+
}
|
179 |
+
|
180 |
+
$result = array_merge(array(
|
181 |
+
'reindex_all' => false,
|
182 |
+
), $result);
|
183 |
+
|
184 |
+
return $result;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @throws Exception
|
189 |
+
* @return Varien_Simplexml_Element[]
|
190 |
+
*/
|
191 |
+
protected function _sortTargetsByDependency() {
|
192 |
+
$targets = array();
|
193 |
+
|
194 |
+
if ($this->getXml()->targets) {
|
195 |
+
foreach ($this->getXml()->targets->children() as $target) {
|
196 |
+
$targets[] = $target;
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
if ($count = count($targets)) {
|
201 |
+
$orders = array();
|
202 |
+
for ($position = 0; $position < $count; $position++) {
|
203 |
+
$found = false;
|
204 |
+
foreach ($targets as $target) {
|
205 |
+
if (!isset($orders[$target->getName()])) {
|
206 |
+
$hasUnresolvedDependency = false;
|
207 |
+
if (isset($target->depends)) {
|
208 |
+
foreach ($target->depends->children() as $dependency) {
|
209 |
+
if (!isset($orders[$dependency->getName()])) {
|
210 |
+
// $dependency not yet sorted so $module should wait until that happens
|
211 |
+
$hasUnresolvedDependency = true;
|
212 |
+
break;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
if (!$hasUnresolvedDependency) {
|
217 |
+
$found = $target;
|
218 |
+
break;
|
219 |
+
}
|
220 |
+
}
|
221 |
+
}
|
222 |
+
if ($found) {
|
223 |
+
$found->sort_order = $orders[$found->getName()] = count($orders);
|
224 |
+
}
|
225 |
+
else {
|
226 |
+
$circular = array();
|
227 |
+
foreach ($targets as $target) {
|
228 |
+
if (!isset($orders[$target->getName()])) {
|
229 |
+
$circular[] = $target->getName();
|
230 |
+
}
|
231 |
+
}
|
232 |
+
throw new Exception(sprintf(
|
233 |
+
"Circular target dependency is not allowed. " .
|
234 |
+
"Please check these targets: %s.",
|
235 |
+
implode(', ', $circular)
|
236 |
+
));
|
237 |
+
}
|
238 |
+
}
|
239 |
+
uasort($targets, array($this, '_compareBySortOrder'));
|
240 |
+
}
|
241 |
+
|
242 |
+
return $targets;
|
243 |
+
}
|
244 |
+
|
245 |
+
protected function _compareBySortOrder($a, $b) {
|
246 |
+
if (((int)(string)$a->sort_order) < ((int)(string)$b->sort_order)) return -1;
|
247 |
+
if (((int)(string)$a->sort_order) > ((int)(string)$b->sort_order)) return 1;
|
248 |
+
|
249 |
+
return 0;
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* @param Varien_Simplexml_Element $target
|
254 |
+
* @param array $options
|
255 |
+
*/
|
256 |
+
protected function _processTarget($target, $options) {
|
257 |
+
$entity = (string)$target->entity;
|
258 |
+
|
259 |
+
/* @var $globalScope Varien_Simplexml_Element */
|
260 |
+
$globalScope = null;
|
261 |
+
/* @var $storeScope Varien_Simplexml_Element */
|
262 |
+
$storeScope = null;
|
263 |
+
|
264 |
+
foreach ($this->dbConfigHelper()->getEntityXml($entity)->scopes->children() as $scope) {
|
265 |
+
if (isset($scope->flattens)) {
|
266 |
+
$flattenedScope = (string)$scope->flattens;
|
267 |
+
if (isset($this->dbConfigHelper()->getScopeXml($flattenedScope)->store_specifics_for)) {
|
268 |
+
$storeScope = $scope;
|
269 |
+
}
|
270 |
+
else {
|
271 |
+
$globalScope = $scope;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
if ($globalScope) {
|
277 |
+
$this->_flattenGlobalScope($target, $globalScope, $options);
|
278 |
+
}
|
279 |
+
if ($storeScope) {
|
280 |
+
$this->_flattenStoreScope($target, $storeScope, $options);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @param Varien_Simplexml_Element $target
|
286 |
+
* @param Varien_Simplexml_Element $scope
|
287 |
+
* @param array $options
|
288 |
+
*/
|
289 |
+
protected function _flattenGlobalScope($target, $scope, $options) {
|
290 |
+
$this->_getResource()->flattenScope($this, $target, $scope, $options);
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* @param Varien_Simplexml_Element $target
|
295 |
+
* @param Varien_Simplexml_Element $scope
|
296 |
+
* @param array $options
|
297 |
+
*/
|
298 |
+
protected function _flattenStoreScope($target, $scope, $options) {
|
299 |
+
$this->_getResource()->flattenScope($this, $target, $scope, $options);
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* @param array $options
|
304 |
+
*/
|
305 |
+
public function process($options = array()) {
|
306 |
+
$options = $this->_prepareOptions($options);
|
307 |
+
$targets = $this->_sortTargetsByDependency();
|
308 |
+
foreach ($targets as $target) {
|
309 |
+
$this->_processTarget($target, $options);
|
310 |
+
}
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Retrieve Indexer description
|
315 |
+
*
|
316 |
+
* @return string
|
317 |
+
*/
|
318 |
+
public function getDescription() {
|
319 |
+
$targets = $this->_sortTargetsByDependency();
|
320 |
+
$descriptions = array();
|
321 |
+
foreach ($targets as $target) {
|
322 |
+
if (isset($target->description)) {
|
323 |
+
$descriptions[] = (string)$target->description;
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
$result = parent::getDescription();
|
328 |
+
if (count($descriptions)) {
|
329 |
+
$result .= ': '.implode(', ', $descriptions);
|
330 |
+
}
|
331 |
+
return $result;
|
332 |
+
}
|
333 |
+
|
334 |
+
#region Dependencies
|
335 |
+
/**
|
336 |
+
* @return Mana_Db_Helper_Config
|
337 |
+
*/
|
338 |
+
public function dbConfigHelper() {
|
339 |
+
return Mage::helper('mana_db/config');
|
340 |
+
}
|
341 |
+
|
342 |
+
/**
|
343 |
+
* @return Mana_Db_Helper_Formula_Processor_Table
|
344 |
+
*/
|
345 |
+
public function tableProcessorHelper() {
|
346 |
+
return Mage::helper('mana_db/formula_processor_table');
|
347 |
+
}
|
348 |
+
#endregion
|
349 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Alias.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
abstract class Mana_Db_Model_Formula_Alias {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Alias $suffix
|
15 |
+
* @return Mana_Db_Model_Formula_Alias
|
16 |
+
*/
|
17 |
+
abstract public function child($suffix);
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param Mana_Db_Model_Formula_Alias_Single $prefix
|
21 |
+
* @return Mana_Db_Model_Formula_Alias
|
22 |
+
*/
|
23 |
+
abstract public function singleChild($prefix);
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param Mana_Db_Model_Formula_Alias_Array $prefix
|
27 |
+
* @return Mana_Db_Model_Formula_Alias
|
28 |
+
*/
|
29 |
+
abstract public function arrayChild($prefix);
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param Mana_Db_Model_Formula_Closure $closure
|
33 |
+
* @return mixed
|
34 |
+
*/
|
35 |
+
abstract public function each($closure);
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @param mixed $index
|
39 |
+
* @return string
|
40 |
+
*/
|
41 |
+
abstract public function asString($index);
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param Mana_Db_Model_Formula_Context $context
|
45 |
+
* @param string $field
|
46 |
+
* @return string | string[]
|
47 |
+
*/
|
48 |
+
public function fieldExpr($context, $field) {
|
49 |
+
return $this->expr($context, "{{= context.$field }}");
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @param Mana_Db_Model_Formula_Context $context
|
54 |
+
* @param string $expr
|
55 |
+
* @return string | string[]
|
56 |
+
*/
|
57 |
+
public abstract function expr($context, $expr);
|
58 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Alias/Array.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Alias_Array extends Mana_Db_Model_Formula_Alias {
|
13 |
+
/**
|
14 |
+
* @var string[]
|
15 |
+
*/
|
16 |
+
protected $_aliases;
|
17 |
+
|
18 |
+
public function __construct($aliases) {
|
19 |
+
$this->_aliases = $aliases;
|
20 |
+
}
|
21 |
+
|
22 |
+
public function getAliases() {
|
23 |
+
return $this->_aliases;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param Mana_Db_Model_Formula_Alias $suffix
|
28 |
+
* @return Mana_Db_Model_Formula_Alias
|
29 |
+
*/
|
30 |
+
public function child($suffix) {
|
31 |
+
return $suffix->arrayChild($this);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param Mana_Db_Model_Formula_Alias_Single $prefix
|
36 |
+
* @return Mana_Db_Model_Formula_Alias
|
37 |
+
*/
|
38 |
+
public function singleChild($prefix) {
|
39 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
40 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
41 |
+
|
42 |
+
$aliases = array();
|
43 |
+
foreach ($this->getAliases() as $index => $alias) {
|
44 |
+
$aliases[$index] = $prefix->getAlias() . '.' . $alias;
|
45 |
+
}
|
46 |
+
|
47 |
+
return $formulaHelper->createAlias($aliases);
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param Mana_Db_Model_Formula_Alias_Array $prefix
|
52 |
+
* @return Mana_Db_Model_Formula_Alias
|
53 |
+
*/
|
54 |
+
public function arrayChild($prefix) {
|
55 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
56 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
57 |
+
|
58 |
+
$aliases = array();
|
59 |
+
foreach ($this->getAliases() as $thisIndex => $thisAlias) {
|
60 |
+
foreach ($prefix->getAliases() as $prefixIndex => $prefixAlias) {
|
61 |
+
$aliases["$prefixIndex.$thisIndex"] = $prefixAlias . '.' . $thisAlias;
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
return $formulaHelper->createAlias($aliases);
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @param Mana_Db_Model_Formula_Closure $closure
|
70 |
+
* @return mixed
|
71 |
+
*/
|
72 |
+
public function each($closure) {
|
73 |
+
$closure->setAlias($this);
|
74 |
+
$result = array();
|
75 |
+
foreach ($this->getAliases() as $index => $alias) {
|
76 |
+
$result[$index] = $closure
|
77 |
+
->setIndex($index)
|
78 |
+
->execute();
|
79 |
+
}
|
80 |
+
return $result;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @param mixed $index
|
85 |
+
* @return string
|
86 |
+
*/
|
87 |
+
public function asString($index) {
|
88 |
+
return $this->_aliases[$index];
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param Mana_Db_Model_Formula_Context $context
|
93 |
+
* @param string $expr
|
94 |
+
* @return string | string[]
|
95 |
+
*/
|
96 |
+
public function expr($context, $expr) {
|
97 |
+
$result = array();
|
98 |
+
foreach ($this->getAliases() as $index => $alias) {
|
99 |
+
$result[$index] = $context->resolveAliases($expr, true, $index);
|
100 |
+
}
|
101 |
+
return $result;
|
102 |
+
}
|
103 |
+
|
104 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Alias/Empty.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Alias_Empty extends Mana_Db_Model_Formula_Alias {
|
13 |
+
/**
|
14 |
+
* @param Mana_Db_Model_Formula_Alias $suffix
|
15 |
+
* @return Mana_Db_Model_Formula_Alias
|
16 |
+
*/
|
17 |
+
public function child($suffix) {
|
18 |
+
return $suffix;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param Mana_Db_Model_Formula_Alias_Single $prefix
|
23 |
+
* @throws Exception
|
24 |
+
* @return Mana_Db_Model_Formula_Alias
|
25 |
+
*/
|
26 |
+
public function singleChild($prefix) {
|
27 |
+
return $prefix;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @param Mana_Db_Model_Formula_Alias_Array $prefix
|
32 |
+
* @throws Exception
|
33 |
+
* @return Mana_Db_Model_Formula_Alias
|
34 |
+
*/
|
35 |
+
public function arrayChild($prefix) {
|
36 |
+
return $prefix;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param Mana_Db_Model_Formula_Closure $closure
|
41 |
+
* @return mixed
|
42 |
+
*/
|
43 |
+
public function each($closure) {
|
44 |
+
return $closure
|
45 |
+
->setIndex(null)
|
46 |
+
->setAlias($this)
|
47 |
+
->execute();
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param mixed $index
|
52 |
+
* @throws Exception
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
public function asString($index) {
|
56 |
+
return 'primary';
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param Mana_Db_Model_Formula_Context $context
|
61 |
+
* @param string $expr
|
62 |
+
* @throws Exception
|
63 |
+
* @return string | string[]
|
64 |
+
*/
|
65 |
+
public function expr($context, $expr) {
|
66 |
+
return $context->resolveAliases($expr);
|
67 |
+
}
|
68 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Alias/Single.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Alias_Single extends Mana_Db_Model_Formula_Alias {
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
protected $_alias;
|
17 |
+
public function __construct($alias) {
|
18 |
+
$this->_alias = $alias;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function getAlias() {
|
22 |
+
return $this->_alias;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param Mana_Db_Model_Formula_Alias $suffix
|
27 |
+
* @return Mana_Db_Model_Formula_Alias
|
28 |
+
*/
|
29 |
+
public function child($suffix) {
|
30 |
+
return $suffix->singleChild($this);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param Mana_Db_Model_Formula_Alias_Single $prefix
|
35 |
+
* @return Mana_Db_Model_Formula_Alias
|
36 |
+
*/
|
37 |
+
public function singleChild($prefix) {
|
38 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
39 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
40 |
+
|
41 |
+
return $formulaHelper->createAlias($prefix->getAlias().'.'.$this->getAlias());
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @param Mana_Db_Model_Formula_Alias_Array $prefix
|
46 |
+
* @return Mana_Db_Model_Formula_Alias
|
47 |
+
*/
|
48 |
+
public function arrayChild($prefix) {
|
49 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
50 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
51 |
+
|
52 |
+
$aliases = array();
|
53 |
+
foreach ($prefix->getAliases() as $index => $alias) {
|
54 |
+
$aliases[$index] = $alias . '.' . $this->getAlias();
|
55 |
+
}
|
56 |
+
return $formulaHelper->createAlias($aliases);
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param Mana_Db_Model_Formula_Closure $closure
|
61 |
+
* @return mixed
|
62 |
+
*/
|
63 |
+
public function each($closure) {
|
64 |
+
return $closure
|
65 |
+
->setIndex(null)
|
66 |
+
->setAlias($this)
|
67 |
+
->execute();
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @param mixed $index
|
72 |
+
* @return string
|
73 |
+
*/
|
74 |
+
public function asString($index) {
|
75 |
+
return $this->getAlias();
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @param Mana_Db_Model_Formula_Context $context
|
80 |
+
* @param string $expr
|
81 |
+
* @return string | string[]
|
82 |
+
*/
|
83 |
+
public function expr($context, $expr) {
|
84 |
+
return $context->resolveAliases($expr);
|
85 |
+
}
|
86 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Closure.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method mixed getIndex()
|
11 |
+
* @method Mana_Db_Model_Formula_Closure setIndex(mixed $value)
|
12 |
+
* @method Mana_Db_Model_Formula_Alias getAlias()
|
13 |
+
* @method Mana_Db_Model_Formula_Closure setAlias(Mana_Db_Model_Formula_Alias $value)
|
14 |
+
*/
|
15 |
+
class Mana_Db_Model_Formula_Closure extends Mana_Core_Model_Closure {
|
16 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Closure/AggregateFieldJoin.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mana_Db_Model_Formula_Context getContext()
|
11 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setContext(Mana_Db_Model_Formula_Context $value)
|
12 |
+
* @method int getTargetIndex()
|
13 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setTargetIndex(int $value)
|
14 |
+
* @method Mana_Db_Model_Formula_Entity getResult()
|
15 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setResult(Mana_Db_Model_Formula_Entity $value)
|
16 |
+
* @method array getCompositeAlias()
|
17 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setCompositeAlias(array $value)
|
18 |
+
* @method array getFields()
|
19 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setFields(array $value)
|
20 |
+
* @method string getEntityName()
|
21 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setEntityName(string $value)
|
22 |
+
* @method Varien_Simplexml_Element getFieldXml()
|
23 |
+
* @method Mana_Db_Model_Formula_Closure_AggregateFieldJoin setFieldXml(Varien_Simplexml_Element $value)
|
24 |
+
*
|
25 |
+
*/
|
26 |
+
class Mana_Db_Model_Formula_Closure_AggregateFieldJoin extends Mana_Db_Model_Formula_Closure {
|
27 |
+
/**
|
28 |
+
* @return mixed|void
|
29 |
+
*/
|
30 |
+
public function execute() {
|
31 |
+
$context = $this->getContext();
|
32 |
+
$fieldXml = $this->getFieldXml();
|
33 |
+
|
34 |
+
$fieldAlias = $this->getAlias()->asString($this->getIndex());
|
35 |
+
|
36 |
+
$compositeAlias = $this->getCompositeAlias() ? $this->getCompositeAlias() : array();
|
37 |
+
$compositeAlias[$this->getTargetIndex()] = $fieldAlias;
|
38 |
+
$this->setCompositeAlias($compositeAlias);
|
39 |
+
|
40 |
+
$fields = $this->getFields() ? $this->getFields() : array();
|
41 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
42 |
+
$fields[$this->getTargetIndex()] = array(
|
43 |
+
'alias' => $fieldAlias,
|
44 |
+
'entity' => (string)$fieldXml->foreign->entity,
|
45 |
+
'join' => "{{= {$fieldAlias}.{$this->getResult()->getProcessor()->getPrimaryKey($this->getEntityName())} }} = " .
|
46 |
+
"{{= {$context->getAlias()->asString($this->getIndex())}.{$fieldXml->getName()} }}",
|
47 |
+
);
|
48 |
+
$this->setFields($fields);
|
49 |
+
}
|
50 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Closure/ForeignJoin.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mana_Db_Model_Formula_Context getContext()
|
11 |
+
* @method Mana_Db_Model_Formula_Closure_ForeignJoin setContext(Mana_Db_Model_Formula_Context $value)
|
12 |
+
* @method Mana_Db_Model_Formula_Entity getEntity()
|
13 |
+
* @method Mana_Db_Model_Formula_Closure_ForeignJoin setEntity(Mana_Db_Model_Formula_Entity $value)
|
14 |
+
*/
|
15 |
+
class Mana_Db_Model_Formula_Closure_ForeignJoin extends Mana_Db_Model_Formula_Closure {
|
16 |
+
/**
|
17 |
+
* @return mixed|void
|
18 |
+
*/
|
19 |
+
public function execute() {
|
20 |
+
/* @var $dbConfig Mana_Db_Helper_Config */
|
21 |
+
$dbConfig = Mage::helper('mana_db/config');
|
22 |
+
|
23 |
+
$entity = $this->getEntity();
|
24 |
+
$context = $this->getContext();
|
25 |
+
return "{{= {$entity->getAlias()->asString($this->getIndex())}.{$entity->getProcessor()->getPrimaryKey($entity->getEntity())} }} = " .
|
26 |
+
"{{= {$context->getAlias()->asString($this->getIndex())}.{$dbConfig->getForeignKey($entity->getEntity(), $context->getEntity())} }}";
|
27 |
+
}
|
28 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Closure/ForeignJoinEnd.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mana_Db_Model_Formula_Context getContext()
|
11 |
+
* @method Mana_Db_Model_Formula_Closure_ForeignJoin setContext(Mana_Db_Model_Formula_Context $value)
|
12 |
+
* @method Mana_Db_Model_Formula_Entity getEntity()
|
13 |
+
* @method Mana_Db_Model_Formula_Closure_ForeignJoin setEntity(Mana_Db_Model_Formula_Entity $value)
|
14 |
+
*/
|
15 |
+
class Mana_Db_Model_Formula_Closure_ForeignJoinEnd extends Mana_Db_Model_Formula_Closure {
|
16 |
+
/**
|
17 |
+
* @return mixed|void
|
18 |
+
*/
|
19 |
+
public function execute() {
|
20 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
21 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
22 |
+
|
23 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
24 |
+
$dbHelper = Mage::helper('mana_db');
|
25 |
+
|
26 |
+
$entity = $this->getEntity();
|
27 |
+
$context = $this->getContext();
|
28 |
+
|
29 |
+
$context->getSelect()->joinLeft(
|
30 |
+
array(
|
31 |
+
$context->registerAlias($entity->getAlias()->asString($this->getIndex())) =>
|
32 |
+
$resource->getTable($dbHelper->getScopedName($entity->getEntity()))
|
33 |
+
),
|
34 |
+
$context->resolveAliases($entity->getForeignJoin()),
|
35 |
+
null
|
36 |
+
);
|
37 |
+
}
|
38 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Closure/Join.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mana_Db_Model_Formula_Context getContext()
|
11 |
+
* @method Mana_Db_Model_Formula_Closure_Join setContext(Mana_Db_Model_Formula_Context $value)
|
12 |
+
* @method Varien_Simplexml_Element getDefinition()
|
13 |
+
* @method Mana_Db_Model_Formula_Closure_Join setDefinitionVarien_Simplexml_Element $value)
|
14 |
+
*/
|
15 |
+
class Mana_Db_Model_Formula_Closure_Join extends Mana_Db_Model_Formula_Closure {
|
16 |
+
/**
|
17 |
+
* @return mixed|void
|
18 |
+
*/
|
19 |
+
public function execute() {
|
20 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
21 |
+
$dbHelper = Mage::helper('mana_db');
|
22 |
+
|
23 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
24 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
25 |
+
|
26 |
+
$definition = $this->getDefinition();
|
27 |
+
$alias = $definition->getName();
|
28 |
+
$fullAlias = $this->getAlias()->asString($this->getIndex());
|
29 |
+
|
30 |
+
$this->getContext()->addLocalAlias($alias, $this->getAlias());
|
31 |
+
if (!$this->getContext()->hasAlias($fullAlias)) {
|
32 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
33 |
+
$entity = $alias == 'primary' ? $this->getContext()->getPrimaryEntity() : (string)$definition->entity;
|
34 |
+
$method = isset($definition->type) ? 'join' . ucfirst($definition->type) : 'joinInner';
|
35 |
+
|
36 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
37 |
+
$this->getContext()->getSelect()->$method(
|
38 |
+
array($this->getContext()->registerAlias($fullAlias) => $resource->getTable($dbHelper->getScopedName($entity))),
|
39 |
+
$this->getContext()->resolveAliases((string)$definition->on, true, $this->getIndex()),
|
40 |
+
null
|
41 |
+
);
|
42 |
+
}
|
43 |
+
}
|
44 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Context.php
ADDED
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getMode()
|
11 |
+
* @method Mana_Db_Model_Formula_Context setMode(string $value)
|
12 |
+
* @method string getPrefix()
|
13 |
+
* @method Mana_Db_Model_Formula_Context setPrefix(string $value)
|
14 |
+
* @method string getEntity()
|
15 |
+
* @method Mana_Db_Model_Formula_Context setEntity(string $value)
|
16 |
+
* @method string getTargetEntity()
|
17 |
+
* @method Mana_Db_Model_Formula_Context setTargetEntity(string $value)
|
18 |
+
* @method string getPrimaryEntity()
|
19 |
+
* @method Mana_Db_Model_Formula_Context setPrimaryEntity(string $value)
|
20 |
+
* @method Mage_Core_Model_Abstract getModel()
|
21 |
+
* @method Mana_Db_Model_Formula_Context setModel(Mage_Core_Model_Abstract $value)
|
22 |
+
* @method Mana_Db_Helper_Formula_Processor getProcessor()
|
23 |
+
* @method mixed getResult()
|
24 |
+
* @method Mana_Db_Model_Formula_Context setResult(mixed $value)
|
25 |
+
* @method Mana_Db_Model_Formula_Field getField()
|
26 |
+
* @method Mana_Db_Model_Formula_Context setField(Mana_Db_Model_Formula_Field $value)
|
27 |
+
* @method Mana_Db_Helper_Formula_Abstract getHelper()
|
28 |
+
* @method Mana_Db_Model_Formula_Context setHelper(Mana_Db_Helper_Formula_Abstract $value)
|
29 |
+
* @method bool getIsAggregate()
|
30 |
+
* @method Mana_Db_Model_Formula_Context setIsAggregate(bool $value)
|
31 |
+
* @method Mana_Db_Model_Formula_Context getParentContext()
|
32 |
+
* @method Mana_Db_Model_Formula_Context setParentContext(Mana_Db_Model_Formula_Context $value)
|
33 |
+
* @method Mana_Db_Model_Formula_Context getAggregateContext()
|
34 |
+
* @method Mana_Db_Model_Formula_Context setAggregateContext(Mana_Db_Model_Formula_Context $value)
|
35 |
+
* @method Mana_Db_Model_Formula_Alias getAlias()
|
36 |
+
* @method Mana_Db_Model_Formula_Context setAlias(Mana_Db_Model_Formula_Alias $value)
|
37 |
+
* @method string __getGlobalEntity()
|
38 |
+
* @method Mana_Db_Model_Formula_Context __setGlobalEntity(string $value)
|
39 |
+
* @method Mana_Db_Helper_Formula_Entity getEntityHelper()
|
40 |
+
* @method Mana_Db_Model_Formula_Context setEntityHelper(Mana_Db_Helper_Formula_Entity $value)
|
41 |
+
*/
|
42 |
+
class Mana_Db_Model_Formula_Context extends Varien_Object {
|
43 |
+
/**
|
44 |
+
* @var Varien_Db_Select()
|
45 |
+
*/
|
46 |
+
protected $_select;
|
47 |
+
/**
|
48 |
+
* @var string[]
|
49 |
+
*/
|
50 |
+
protected $_fields = array();
|
51 |
+
protected $_aliases = array();
|
52 |
+
protected $_localAliases = array();
|
53 |
+
|
54 |
+
protected $_options = array();
|
55 |
+
|
56 |
+
static protected $_quoteFieldsAndEntities = true;
|
57 |
+
static protected $_aliasIndex = null;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param Mana_Db_Helper_Formula_Processor | string $processor
|
61 |
+
* @return Mana_Db_Model_Formula_Context
|
62 |
+
*/
|
63 |
+
public function setProcessor($processor) {
|
64 |
+
if (is_string($processor)) {
|
65 |
+
$processor = Mage::helper('mana_db/formula_processor_' . $processor);
|
66 |
+
}
|
67 |
+
$this->setData('processor', $processor);
|
68 |
+
|
69 |
+
return $this;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @return Mana_Db_Model_Formula_Context
|
74 |
+
*/
|
75 |
+
public function createChildContext() {
|
76 |
+
/* @var $result Mana_Db_Model_Formula_Context */
|
77 |
+
$result = Mage::getModel('mana_db/formula_context');
|
78 |
+
return $result
|
79 |
+
->setHelper($this->getHelper())
|
80 |
+
->setParentContext($this);
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @param Mana_Db_Model_Formula_Context $context
|
85 |
+
* @return Mana_Db_Model_Formula_Context
|
86 |
+
*/
|
87 |
+
public function copyAliases($context) {
|
88 |
+
$this->_aliases = $context->_aliases;
|
89 |
+
return $this;
|
90 |
+
}
|
91 |
+
|
92 |
+
public function registerAlias($alias) {
|
93 |
+
if (!isset($this->_aliases[$alias])) {
|
94 |
+
$relativeAlias = explode('.', $alias);
|
95 |
+
$relativeAlias = array_pop($relativeAlias);
|
96 |
+
$letter = $this->getPrefix().substr($relativeAlias, 0, 1);
|
97 |
+
for ($i = 1, $result = $letter; in_array($result, $this->_aliases); $i++, $result = $letter . $i) ;
|
98 |
+
$this->_aliases[$alias] = $result;
|
99 |
+
}
|
100 |
+
return $this->_aliases[$alias];
|
101 |
+
}
|
102 |
+
|
103 |
+
public function resolveAliases($expr, $quoteFieldsAndEntities = true, $aliasIndex = null) {
|
104 |
+
self::$_quoteFieldsAndEntities = $quoteFieldsAndEntities;
|
105 |
+
self::$_aliasIndex = $aliasIndex;
|
106 |
+
return preg_replace_callback('/{{=([^}]*)}}/', array($this, '_resolveAlias'), $expr);
|
107 |
+
}
|
108 |
+
|
109 |
+
public function hasAlias($alias) {
|
110 |
+
return isset($this->_aliases[$alias]);
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
public function resetLocalAliases() {
|
115 |
+
$this->_localAliases = array();
|
116 |
+
|
117 |
+
return $this;
|
118 |
+
}
|
119 |
+
|
120 |
+
public function addLocalAlias($localAlias, $globalAlias) {
|
121 |
+
$this->_localAliases[$localAlias] = $globalAlias;
|
122 |
+
return $this;
|
123 |
+
}
|
124 |
+
|
125 |
+
protected function _resolveAlias($matches) {
|
126 |
+
return $this->_doResolveAlias($matches[1]);
|
127 |
+
}
|
128 |
+
|
129 |
+
public function resolveAlias($fieldExpr, $quoteFieldsAndEntities = true, $aliasIndex = null) {
|
130 |
+
self::$_quoteFieldsAndEntities = $quoteFieldsAndEntities;
|
131 |
+
self::$_aliasIndex = $aliasIndex;
|
132 |
+
return $this->_doResolveAlias($fieldExpr);
|
133 |
+
}
|
134 |
+
protected function _doResolveAlias($fieldExpr) {
|
135 |
+
$fieldExpr = explode('.', $fieldExpr);
|
136 |
+
foreach ($fieldExpr as $index => $field) {
|
137 |
+
$fieldExpr[$index] = trim($field);
|
138 |
+
}
|
139 |
+
if ($fieldExpr[0] == 'parent') {
|
140 |
+
return $this->getParentContext()->_doResolveAlias(implode('.', array_slice($fieldExpr, 1)));
|
141 |
+
}
|
142 |
+
else {
|
143 |
+
$field = array_pop($fieldExpr);
|
144 |
+
$alias = implode('.', $fieldExpr);
|
145 |
+
if (!$alias) {
|
146 |
+
$alias = 'primary';
|
147 |
+
}
|
148 |
+
|
149 |
+
if ($fieldExpr[0] == 'context') {
|
150 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
151 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
152 |
+
|
153 |
+
$alias = $this->getAlias()->child($formulaHelper->createAlias(implode('.', array_slice($fieldExpr, 1))));
|
154 |
+
}
|
155 |
+
elseif (isset($this->_localAliases[$alias])) {
|
156 |
+
$alias = $this->_localAliases[$alias];
|
157 |
+
}
|
158 |
+
|
159 |
+
if (!is_string($alias)) {
|
160 |
+
$alias = $alias->asString(self::$_aliasIndex);
|
161 |
+
}
|
162 |
+
|
163 |
+
if (self::$_quoteFieldsAndEntities) {
|
164 |
+
return "`{$this->registerAlias($alias)}`.`$field`";
|
165 |
+
}
|
166 |
+
else {
|
167 |
+
return "{$this->registerAlias($alias)}.$field";
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @return Varien_Db_Select
|
174 |
+
*/
|
175 |
+
public function getSelect() {
|
176 |
+
if (!$this->_select) {
|
177 |
+
/* @var $resource Mana_Db_Resource_Formula */
|
178 |
+
$resource = Mage::getResourceSingleton('mana_db/formula');
|
179 |
+
|
180 |
+
$this->_select = $resource->select();
|
181 |
+
}
|
182 |
+
return $this->_select;
|
183 |
+
}
|
184 |
+
|
185 |
+
public function incrementPrefix() {
|
186 |
+
$alias = $this->getAlias() ? $this->getAlias() : 'primary';
|
187 |
+
$prefix = $this->getPrefix() . $this->registerAlias($alias);
|
188 |
+
$this->setPrefix($prefix);
|
189 |
+
return $prefix;
|
190 |
+
}
|
191 |
+
|
192 |
+
public function decrementPrefix() {
|
193 |
+
$alias = $this->getAlias() ? $this->getAlias() : 'primary';
|
194 |
+
$prefix = substr($this->getPrefix(), 0, strlen($this->getPrefix()) - strlen($this->registerAlias($alias)));
|
195 |
+
$this->setPrefix($prefix);
|
196 |
+
|
197 |
+
return $prefix;
|
198 |
+
}
|
199 |
+
|
200 |
+
public function getFields() {
|
201 |
+
return $this->_fields;
|
202 |
+
}
|
203 |
+
|
204 |
+
public function addField($field) {
|
205 |
+
$this->_fields[] = $field;
|
206 |
+
return $this;
|
207 |
+
}
|
208 |
+
|
209 |
+
public function setOptions($options) {
|
210 |
+
$this->_options = $options;
|
211 |
+
return $this;
|
212 |
+
}
|
213 |
+
|
214 |
+
public function getOption($option) {
|
215 |
+
return isset($this->_options[$option]) ? $this->_options[$option] : false;
|
216 |
+
}
|
217 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Entity.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mana_Db_Helper_Formula_Entity getHelper()
|
11 |
+
* @method Mana_Db_Model_Formula_Alias getAlias()
|
12 |
+
* @method Mana_Db_Model_Formula_Entity setAlias(Mana_Db_Model_Formula_Alias $value)
|
13 |
+
* @method string getForeignJoin()
|
14 |
+
* @method Mana_Db_Model_Formula_Entity setForeignJoin(string $value)
|
15 |
+
* @method string getEntity()
|
16 |
+
* @method Mana_Db_Model_Formula_Entity setEntity(string $value)
|
17 |
+
* @method string[] | bool getJoin()
|
18 |
+
* @method Mana_Db_Model_Formula_Entity setJoin(array $value)
|
19 |
+
* @method string getOrder()
|
20 |
+
* @method Mana_Db_Model_Formula_Entity setOrder(string $value)
|
21 |
+
* @method string getWhere()
|
22 |
+
* @method Mana_Db_Model_Formula_Entity setWhere(string $value)
|
23 |
+
* @method Mana_Db_Helper_Formula_Processor getProcessor()
|
24 |
+
* @method string[] | bool getAggregateFields()
|
25 |
+
* @method Mana_Db_Model_Formula_Entity setAggregateFields(array $value)
|
26 |
+
*/
|
27 |
+
class Mana_Db_Model_Formula_Entity extends Varien_Object {
|
28 |
+
/**
|
29 |
+
* @param Mana_Db_Helper_Formula_Entity | string $entity
|
30 |
+
* @return Mana_Db_Model_Formula_Entity
|
31 |
+
*/
|
32 |
+
public function setHelper($entity) {
|
33 |
+
if (is_string($entity)) {
|
34 |
+
$entity = Mage::helper('mana_db/formula_entity_' . $entity);
|
35 |
+
}
|
36 |
+
$this->setData('helper', $entity);
|
37 |
+
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param Mana_Db_Helper_Formula_Processor | string $processor
|
43 |
+
* @return Mana_Db_Model_Formula_Entity
|
44 |
+
*/
|
45 |
+
public function setProcessor($processor) {
|
46 |
+
if (is_string($processor)) {
|
47 |
+
$processor = Mage::helper('mana_db/formula_processor_' . $processor);
|
48 |
+
}
|
49 |
+
$this->setData('processor', $processor);
|
50 |
+
|
51 |
+
return $this;
|
52 |
+
}
|
53 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Expr.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getType()
|
11 |
+
* @method Mana_Db_Model_Formula_Expr setType(string $value)
|
12 |
+
* @method string getExpr()
|
13 |
+
* @method Mana_Db_Model_Formula_Expr setExpr(string $value)
|
14 |
+
* @method string | string[] getFieldExpr()
|
15 |
+
* @method Mana_Db_Model_Formula_Expr setFieldExpr(mixed $value)
|
16 |
+
* @method string getFieldName()
|
17 |
+
* @method Mana_Db_Model_Formula_Expr setFieldName(string $value)
|
18 |
+
* @method Varien_Db_Select getSubSelect()
|
19 |
+
* @method Mana_Db_Model_Formula_Expr setSubSelect(Varien_Db_Select $value)
|
20 |
+
* @method bool getIsAggregate()
|
21 |
+
* @method Mana_Db_Model_Formula_Expr setIsAggregate(bool $value)
|
22 |
+
* @method bool getIsFrontend()
|
23 |
+
* @method Mana_Db_Model_Formula_Expr setIsFrontend(bool $value)
|
24 |
+
*/
|
25 |
+
class Mana_Db_Model_Formula_Expr extends Varien_Object {
|
26 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Field.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getName()
|
11 |
+
* @method Mana_Db_Model_Formula_Field setName(string $value)
|
12 |
+
* @method string getType()
|
13 |
+
* @method Mana_Db_Model_Formula_Field setType(string $value)
|
14 |
+
* @method string getRole()
|
15 |
+
* @method Mana_Db_Model_Formula_Field setRole(string $value)
|
16 |
+
* @method int getNo()
|
17 |
+
* @method Mana_Db_Model_Formula_Field setNo(int $value)
|
18 |
+
* @method bool hasFormula()
|
19 |
+
* @method Mana_Db_Model_Formula_Node getFormula()
|
20 |
+
* @method Mana_Db_Model_Formula_Field setFormula(Mana_Db_Model_Formula_Node $value)
|
21 |
+
* @method bool hasValue()
|
22 |
+
* @method string getValue()
|
23 |
+
* @method Mana_Db_Model_Formula_Field setValue(string $value)
|
24 |
+
* @method bool hasDependencies()
|
25 |
+
* @method string[] getDependencies()
|
26 |
+
* @method Mana_Db_Model_Formula_Field setDependencies(array $value)
|
27 |
+
* @method string getFormulaString()
|
28 |
+
* @method Mana_Db_Model_Formula_Field setFormulaString(string $value)
|
29 |
+
*/
|
30 |
+
class Mana_Db_Model_Formula_Field extends Varien_Object {
|
31 |
+
/**
|
32 |
+
* @param Mana_Db_Model_Entity $model
|
33 |
+
* @return bool
|
34 |
+
*/
|
35 |
+
public function useDefault($model) {
|
36 |
+
}
|
37 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*/
|
11 |
+
class Mana_Db_Model_Formula_Node {
|
12 |
+
public function __construct($data = array()) {
|
13 |
+
foreach ($data as $property => $value) {
|
14 |
+
$this->$property = $value;
|
15 |
+
}
|
16 |
+
}
|
17 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/Add.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_Add extends Mana_Db_Model_Formula_Node {
|
13 |
+
const ADD = Mana_Db_Helper_Formula_Parser::ADD;
|
14 |
+
const SUBTRACT = Mana_Db_Helper_Formula_Parser::SUBTRACT;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var int
|
18 |
+
*/
|
19 |
+
public $operator;
|
20 |
+
/**
|
21 |
+
* @var Mana_Db_Model_Formula_Node
|
22 |
+
*/
|
23 |
+
public $a;
|
24 |
+
/**
|
25 |
+
* @var Mana_Db_Model_Formula_Node
|
26 |
+
*/
|
27 |
+
public $b;
|
28 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/Field.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_Field extends Mana_Db_Model_Formula_Node {
|
13 |
+
/**
|
14 |
+
* @var string[]
|
15 |
+
*/
|
16 |
+
public $identifiers;
|
17 |
+
|
18 |
+
public function __toString() {
|
19 |
+
return implode('.', $this->identifiers);
|
20 |
+
}
|
21 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/FormulaExpr.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_FormulaExpr extends Mana_Db_Model_Formula_Node {
|
13 |
+
/**
|
14 |
+
* @var Mana_Db_Model_Formula_Node[]
|
15 |
+
*/
|
16 |
+
public $parts;
|
17 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/FunctionCall.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_FunctionCall extends Mana_Db_Model_Formula_Node {
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
public $name;
|
17 |
+
/**
|
18 |
+
* @var Mana_Db_Model_Formula_Node[]
|
19 |
+
*/
|
20 |
+
public $args;
|
21 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/Identifier.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_Identifier extends Mana_Db_Model_Formula_Node {
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
public $identifier;
|
17 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/Multiply.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_Multiply extends Mana_Db_Model_Formula_Node {
|
13 |
+
const MULTIPLY = Mana_Db_Helper_Formula_Parser::MULTIPLY;
|
14 |
+
const DIVIDE = Mana_Db_Helper_Formula_Parser::DIVIDE;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var int
|
18 |
+
*/
|
19 |
+
public $operator;
|
20 |
+
/**
|
21 |
+
* @var Mana_Db_Model_Formula_Node
|
22 |
+
*/
|
23 |
+
public $a;
|
24 |
+
/**
|
25 |
+
* @var Mana_Db_Model_Formula_Node
|
26 |
+
*/
|
27 |
+
public $b;
|
28 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/NullValue.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_NullValue extends Mana_Db_Model_Formula_Node {
|
13 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/NumberConstant.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_NumberConstant extends Mana_Db_Model_Formula_Node {
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
public $value;
|
17 |
+
}
|
app/code/local/Mana/Db/Model/Formula/Node/StringConstant.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Formula_Node_StringConstant extends Mana_Db_Model_Formula_Node {
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
public $value;
|
17 |
+
}
|
app/code/local/Mana/Db/Model/Indexer.php
CHANGED
@@ -20,7 +20,7 @@ class Mana_Db_Model_Indexer extends Mage_Index_Model_Indexer_Abstract {
|
|
20 |
}
|
21 |
public function getName()
|
22 |
{
|
23 |
-
return Mage::helper('mana_db')->__('Default Values');
|
24 |
}
|
25 |
public function getDescription()
|
26 |
{
|
20 |
}
|
21 |
public function getName()
|
22 |
{
|
23 |
+
return Mage::helper('mana_db')->__('Default Values (MANAdev)');
|
24 |
}
|
25 |
public function getDescription()
|
26 |
{
|
app/code/local/Mana/Db/Model/Observer.php
CHANGED
@@ -28,7 +28,19 @@ class Mana_Db_Model_Observer {
|
|
28 |
Mage::unregister('m_run_db_replication');
|
29 |
$this->_getProcess()->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX)->reindexAll();
|
30 |
}
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
/**
|
33 |
* Enter description here ...
|
34 |
* @param unknown_type $observer
|
@@ -101,13 +113,28 @@ class Mana_Db_Model_Observer {
|
|
101 |
* Runs data replication actions if related configuration changed (handles event "core_config_data_save_commit_after")
|
102 |
* @param Varien_Event_Observer $observer
|
103 |
*/
|
104 |
-
public function
|
105 |
-
$
|
106 |
-
if ($
|
107 |
-
Mage::helper('mana_db')->isReplicatedConfigChanged($
|
108 |
{
|
109 |
Mage::register('m_run_db_replication', true);
|
110 |
}
|
|
|
|
|
|
|
|
|
|
|
111 |
}
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
28 |
Mage::unregister('m_run_db_replication');
|
29 |
$this->_getProcess()->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX)->reindexAll();
|
30 |
}
|
31 |
+
|
32 |
+
/* @var $indexer Mage_Index_Model_Indexer */
|
33 |
+
$indexer = Mage::getSingleton('index/indexer');
|
34 |
+
|
35 |
+
if ($reindex = Mage::registry('m_reindex')) {
|
36 |
+
foreach ($reindex as $code) {
|
37 |
+
$indexer->getProcessByCode($code)
|
38 |
+
->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX)
|
39 |
+
->reindexAll();
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
}
|
44 |
/**
|
45 |
* Enter description here ...
|
46 |
* @param unknown_type $observer
|
113 |
* Runs data replication actions if related configuration changed (handles event "core_config_data_save_commit_after")
|
114 |
* @param Varien_Event_Observer $observer
|
115 |
*/
|
116 |
+
public function afterSaveCommit($observer) {
|
117 |
+
$object = $observer->getEvent()->getObject();
|
118 |
+
if ($object->getResourceName() == 'core/config_data' &&
|
119 |
+
Mage::helper('mana_db')->isReplicatedConfigChanged($object))
|
120 |
{
|
121 |
Mage::register('m_run_db_replication', true);
|
122 |
}
|
123 |
+
elseif ($object->getResourceName() == 'cms/page') {
|
124 |
+
if (!Mage::registry('m_prevent_indexing_on_save')) {
|
125 |
+
$this->getIndexerSingleton()->processEntityAction($object, 'cms/page', Mage_Index_Model_Event::TYPE_SAVE);
|
126 |
+
}
|
127 |
+
}
|
128 |
}
|
129 |
+
|
130 |
+
public function afterConfigSave($observer) {}
|
131 |
+
|
132 |
+
#region Dependencies
|
133 |
+
/**
|
134 |
+
* @return Mage_Index_Model_Indexer
|
135 |
+
*/
|
136 |
+
public function getIndexerSingleton() {
|
137 |
+
return Mage::getSingleton('index/indexer');
|
138 |
+
}
|
139 |
+
#endregion
|
140 |
}
|
app/code/local/Mana/Db/Model/Setup.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mage_Core_Model_Resource_Setup getInstaller()
|
11 |
+
* @method Mana_Db_Model_Setup setInstaller(Mage_Core_Model_Resource_Setup $value)
|
12 |
+
* @method string getModuleName()
|
13 |
+
* @method Mana_Db_Model_Setup setModuleName(string $value)
|
14 |
+
* @method string getVersion()
|
15 |
+
* @method Mana_Db_Model_Setup setVersion(string $value)
|
16 |
+
* @method string getSetupVersion()
|
17 |
+
* @method Mana_Db_Model_Setup setSetupVersion(string $value)
|
18 |
+
*/
|
19 |
+
class Mana_Db_Model_Setup extends Varien_Object {
|
20 |
+
public function run ($installer, $moduleName, $version) {
|
21 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
22 |
+
$configHelper = Mage::helper('mana_db/config');
|
23 |
+
|
24 |
+
$installerKey = 'v'.$version;
|
25 |
+
$setupVersion = $configHelper->getXml()->getNode()->modules->$moduleName->installer_versions->$installerKey;
|
26 |
+
|
27 |
+
$this
|
28 |
+
->setInstaller($installer)
|
29 |
+
->setModuleName($moduleName)
|
30 |
+
->setVersion($version)
|
31 |
+
->setSetupVersion($setupVersion)
|
32 |
+
->_beforeRun()
|
33 |
+
->_run()
|
34 |
+
->_afterRun();
|
35 |
+
}
|
36 |
+
protected function _beforeRun() {
|
37 |
+
$installer = $this->getInstaller();
|
38 |
+
|
39 |
+
if (defined('COMPILER_INCLUDE_PATH')) {
|
40 |
+
throw new Exception(Mage::helper('mana_core')->__(
|
41 |
+
'This Magento installation contains pending database installation/upgrade scripts. Please turn off Magento compilation feature while installing/upgrading new modules in Admin Panel menu System->Tools->Compilation.'
|
42 |
+
));
|
43 |
+
}
|
44 |
+
|
45 |
+
if (method_exists($installer->getConnection(), 'allowDdlCache')) {
|
46 |
+
$installer->getConnection()->allowDdlCache();
|
47 |
+
}
|
48 |
+
|
49 |
+
return $this;
|
50 |
+
}
|
51 |
+
protected function _run() {
|
52 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
53 |
+
$configHelper = Mage::helper('mana_db/config');
|
54 |
+
|
55 |
+
$setupVersion = $configHelper->getSetup($this->getSetupVersion());
|
56 |
+
$setupVersion->setData($this->getData());
|
57 |
+
$setupVersion->run();
|
58 |
+
|
59 |
+
return $this;
|
60 |
+
}
|
61 |
+
protected function _afterRun() {
|
62 |
+
$installer = $this->getInstaller();
|
63 |
+
|
64 |
+
if (method_exists($installer->getConnection(), 'disallowDdlCache')) {
|
65 |
+
$installer->getConnection()->disallowDdlCache();
|
66 |
+
}
|
67 |
+
$installer->endSetup();
|
68 |
+
|
69 |
+
return $this;
|
70 |
+
}
|
71 |
+
|
72 |
+
public function scheduleReindexing($code) {
|
73 |
+
if ($reindex = Mage::registry('m_reindex')) {
|
74 |
+
Mage::unregister('m_reindex');
|
75 |
+
}
|
76 |
+
else {
|
77 |
+
$reindex = array();
|
78 |
+
}
|
79 |
+
$reindex[$code] = $code;
|
80 |
+
Mage::register('m_reindex', $reindex);
|
81 |
+
|
82 |
+
return $this;
|
83 |
+
}
|
84 |
+
}
|
app/code/local/Mana/Db/Model/Setup/Abstract.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method Mage_Core_Model_Resource_Setup getInstaller()
|
11 |
+
* @method Mana_Db_Model_Setup_Abstract setInstaller(Mage_Core_Model_Resource_Setup $value)
|
12 |
+
* @method string getModuleName()
|
13 |
+
* @method Mana_Db_Model_Setup_Abstract setModuleName(string $value)
|
14 |
+
* @method string getVersion()
|
15 |
+
* @method Mana_Db_Model_Setup_Abstract setVersion(string $value)
|
16 |
+
* @method string getSql()
|
17 |
+
* @method Mana_Db_Model_Setup_Abstract setSql(string $value)
|
18 |
+
*/
|
19 |
+
class Mana_Db_Model_Setup_Abstract extends Varien_Object {
|
20 |
+
public function getTable($entityName) {
|
21 |
+
/* @var $db Mana_Db_Helper_Data */
|
22 |
+
$db = Mage::helper('mana_db');
|
23 |
+
|
24 |
+
return $this->getInstaller()->getTable($db->getScopedName($entityName));
|
25 |
+
}
|
26 |
+
public function prepare() {
|
27 |
+
return $this;
|
28 |
+
}
|
29 |
+
|
30 |
+
public function run() {
|
31 |
+
return $this;
|
32 |
+
}
|
33 |
+
}
|
app/code/local/Mana/Db/Model/Setup/V13012122.php
ADDED
@@ -0,0 +1,478 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Model_Setup_V13012122 extends Mana_Db_Model_Setup_Abstract {
|
13 |
+
protected $_toBeCreated = array();
|
14 |
+
protected $_toBeAltered = array();
|
15 |
+
|
16 |
+
public function prepare() {
|
17 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
18 |
+
$configHelper = Mage::helper('mana_db/config');
|
19 |
+
|
20 |
+
$configHelper->iterate(array('scope' => array($this, '_createPrimaryKey')));
|
21 |
+
$configHelper->iterate(array('scope' => array($this, '_createDefaultValueInfrastructure')));
|
22 |
+
$configHelper->iterate(array('scope' => array($this, '_createStoreSpecificsInfrastructure')));
|
23 |
+
$configHelper->iterate(array('scope' => array($this, '_createGridEditingInfrastructure')));
|
24 |
+
$configHelper->iterate(array('scope' => array($this, '_createFlatInfrastructure')));
|
25 |
+
|
26 |
+
return $this;
|
27 |
+
}
|
28 |
+
|
29 |
+
public function run() {
|
30 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
31 |
+
$configHelper = Mage::helper('mana_db/config');
|
32 |
+
|
33 |
+
$result = $configHelper->iterate(array(
|
34 |
+
'scope_before' => array($this, '_beginTableScript'),
|
35 |
+
'field' => array($this, '_fieldScript'),
|
36 |
+
'scope_after' => array($this, '_endTableScript'),
|
37 |
+
));
|
38 |
+
|
39 |
+
if ($result->getSql()) {
|
40 |
+
$this->getInstaller()->run($result->getSql());
|
41 |
+
}
|
42 |
+
return $this;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param Varien_Object $context
|
47 |
+
* @param Varien_Simplexml_Element $module
|
48 |
+
* @param Varien_Simplexml_Element $entity
|
49 |
+
* @param Varien_Simplexml_Element $scope
|
50 |
+
*/
|
51 |
+
public function _createPrimaryKey($context, $module, $entity, $scope) {
|
52 |
+
if (((string)$scope['module']) != $this->getModuleName() || ((string)$scope['version']) != $this->getVersion()) {
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
56 |
+
$configHelper = Mage::helper('mana_db/config');
|
57 |
+
|
58 |
+
$primaryField = $scope->xpath('fields/*[primary="1"]');
|
59 |
+
if (empty($primaryField)) {
|
60 |
+
$scope->fields->id->type = 'bigint';
|
61 |
+
$field = $scope->fields->id;
|
62 |
+
$field->primary = 1;
|
63 |
+
$field->role = Mana_Db_Helper_Config::ROLE_PRIMARY_KEY;
|
64 |
+
$configHelper->propagateName($field);
|
65 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @param Varien_Object $context
|
71 |
+
* @param Varien_Simplexml_Element $module
|
72 |
+
* @param Varien_Simplexml_Element $entity
|
73 |
+
* @param Varien_Simplexml_Element $scope
|
74 |
+
*/
|
75 |
+
public function _createDefaultValueInfrastructure($context, $module, $entity, $scope) {
|
76 |
+
if (((string)$scope['module']) != $this->getModuleName() || ((string)$scope['version']) != $this->getVersion()) {
|
77 |
+
return;
|
78 |
+
}
|
79 |
+
|
80 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
81 |
+
$configHelper = Mage::helper('mana_db/config');
|
82 |
+
|
83 |
+
if (!empty($scope->max_defaultable_fields) && empty($scope->flattens)) {
|
84 |
+
$maxFields = (int)(string)$scope->max_defaultable_fields;
|
85 |
+
for ($i = 0; $i * 15 < $maxFields; $i++) {
|
86 |
+
$fieldName = "default_mask{$i}";
|
87 |
+
$scope->fields->$fieldName->type = 'int unsigned';
|
88 |
+
$field = $scope->fields->$fieldName;
|
89 |
+
$field->default_value = 0;
|
90 |
+
$field->role = Mana_Db_Helper_Config::ROLE_DEFAULT_VALUE;
|
91 |
+
$configHelper->propagateName($field);
|
92 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
93 |
+
}
|
94 |
+
|
95 |
+
$fieldName = 'default_formula_hash';
|
96 |
+
$scope->fields->$fieldName->type = 'varchar(40)';
|
97 |
+
$field = $scope->fields->$fieldName;
|
98 |
+
$field->indexed = 1;
|
99 |
+
$field->role = Mana_Db_Helper_Config::ROLE_DEFAULT_VALUE;
|
100 |
+
$configHelper->propagateName($field);
|
101 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
102 |
+
|
103 |
+
|
104 |
+
$fieldName = 'default_formulas';
|
105 |
+
$scope->fields->$fieldName->type = 'mediumtext';
|
106 |
+
$field = $scope->fields->$fieldName;
|
107 |
+
$field->role = Mana_Db_Helper_Config::ROLE_DEFAULT_VALUE;
|
108 |
+
$configHelper->propagateName($field);
|
109 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @param Varien_Object $context
|
115 |
+
* @param Varien_Simplexml_Element $module
|
116 |
+
* @param Varien_Simplexml_Element $entity
|
117 |
+
* @param Varien_Simplexml_Element $scope
|
118 |
+
*/
|
119 |
+
public function _createStoreSpecificsInfrastructure($context, $module, $entity, $scope) {
|
120 |
+
if (((string)$scope['module']) != $this->getModuleName() || ((string)$scope['version']) != $this->getVersion()) {
|
121 |
+
return;
|
122 |
+
}
|
123 |
+
|
124 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
125 |
+
$configHelper = Mage::helper('mana_db/config');
|
126 |
+
|
127 |
+
if (!empty($scope->store_specifics_for)) {
|
128 |
+
$globalScope = (string)$scope->store_specifics_for;
|
129 |
+
|
130 |
+
$fieldName = 'global_id';
|
131 |
+
$scope->fields->$fieldName->type = 'bigint';
|
132 |
+
$field = $scope->fields->$fieldName;
|
133 |
+
$field->foreign->entity = $globalScope;
|
134 |
+
$field->foreign->field = 'id';
|
135 |
+
$field->foreign->on_update = 'cascade';
|
136 |
+
$field->foreign->on_delete = 'cascade';
|
137 |
+
$field->role = Mana_Db_Helper_Config::ROLE_STORE_SPECIFICS;
|
138 |
+
$configHelper->propagateName($field);
|
139 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
140 |
+
|
141 |
+
$fieldName = 'store_id';
|
142 |
+
$scope->fields->$fieldName->type = 'smallint(5) unsigned';
|
143 |
+
$field = $scope->fields->$fieldName;
|
144 |
+
$field->foreign->entity = 'core/store';
|
145 |
+
$field->foreign->field = 'store_id';
|
146 |
+
$field->foreign->on_update = 'cascade';
|
147 |
+
$field->foreign->on_delete = 'cascade';
|
148 |
+
$field->role = Mana_Db_Helper_Config::ROLE_STORE_SPECIFICS;
|
149 |
+
$configHelper->propagateName($field);
|
150 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
151 |
+
|
152 |
+
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* @param Varien_Object $context
|
158 |
+
* @param Varien_Simplexml_Element $module
|
159 |
+
* @param Varien_Simplexml_Element $entity
|
160 |
+
* @param Varien_Simplexml_Element $scope
|
161 |
+
*/
|
162 |
+
public function _createGridEditingInfrastructure($context, $module, $entity, $scope) {
|
163 |
+
if (((string)$scope['module']) != $this->getModuleName() || ((string)$scope['version']) != $this->getVersion()) {
|
164 |
+
return;
|
165 |
+
}
|
166 |
+
|
167 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
168 |
+
$configHelper = Mage::helper('mana_db/config');
|
169 |
+
|
170 |
+
if (!empty($scope->editable_in_grid)) {
|
171 |
+
|
172 |
+
$fieldName = 'edit_session_id';
|
173 |
+
$scope->fields->$fieldName->type = 'bigint';
|
174 |
+
$field = $scope->fields->$fieldName;
|
175 |
+
$field->default_value = 0;
|
176 |
+
$field->foreign->entity = 'mana_db/edit_session';
|
177 |
+
$field->foreign->field = 'id';
|
178 |
+
$field->foreign->on_update = 'cascade';
|
179 |
+
$field->foreign->on_delete = 'cascade';
|
180 |
+
$field->role = Mana_Db_Helper_Config::ROLE_GRID_EDITING;
|
181 |
+
$configHelper->propagateName($field);
|
182 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
183 |
+
|
184 |
+
$fieldName = 'edit_status';
|
185 |
+
$scope->fields->$fieldName->type = 'bigint';
|
186 |
+
$field = $scope->fields->$fieldName;
|
187 |
+
$field->default_value = 0;
|
188 |
+
$field->indexed = 1;
|
189 |
+
$field->role = Mana_Db_Helper_Config::ROLE_GRID_EDITING;
|
190 |
+
$configHelper->propagateName($field);
|
191 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
192 |
+
|
193 |
+
$fieldName = 'edit_massaction';
|
194 |
+
$scope->fields->$fieldName->type = 'tinyint';
|
195 |
+
$field = $scope->fields->$fieldName;
|
196 |
+
$field->default_value = 0;
|
197 |
+
$field->indexed = 1;
|
198 |
+
$field->role = Mana_Db_Helper_Config::ROLE_GRID_EDITING;
|
199 |
+
$configHelper->propagateName($field);
|
200 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
201 |
+
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @param Varien_Object $context
|
207 |
+
* @param Varien_Simplexml_Element $module
|
208 |
+
* @param Varien_Simplexml_Element $entity
|
209 |
+
* @param Varien_Simplexml_Element $scope
|
210 |
+
*/
|
211 |
+
public function _createFlatInfrastructure($context, $module, $entity, $scope) {
|
212 |
+
if (((string)$scope['module']) != $this->getModuleName() || ((string)$scope['version']) != $this->getVersion()) {
|
213 |
+
return;
|
214 |
+
}
|
215 |
+
|
216 |
+
/* @var $configHelper Mana_Db_Helper_Config */
|
217 |
+
$configHelper = Mage::helper('mana_db/config');
|
218 |
+
|
219 |
+
if (!empty($scope->flattens)) {
|
220 |
+
$flattenedScopeXml = $configHelper->getScopeXml((string)$scope->flattens);
|
221 |
+
if (!empty($flattenedScopeXml->store_specifics_for)) {
|
222 |
+
$global = (string)$flattenedScopeXml->store_specifics_for;
|
223 |
+
$fieldName = 'global_id';
|
224 |
+
$scope->fields->$fieldName->type = 'bigint';
|
225 |
+
$field = $scope->fields->$fieldName;
|
226 |
+
$field->foreign->entity = substr($global, 0, strrpos($global, '/')).'/flat';
|
227 |
+
$field->foreign->field = 'id';
|
228 |
+
$field->foreign->on_update = 'cascade';
|
229 |
+
$field->foreign->on_delete = 'cascade';
|
230 |
+
$field->role = Mana_Db_Helper_Config::ROLE_STORE_SPECIFICS;
|
231 |
+
$field->default_formula = '{{= global.id }}';
|
232 |
+
$configHelper->propagateName($field);
|
233 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
234 |
+
|
235 |
+
$fieldName = 'store_id';
|
236 |
+
$scope->fields->$fieldName->type = 'smallint(5) unsigned';
|
237 |
+
$field = $scope->fields->$fieldName;
|
238 |
+
$field->foreign->entity = 'core/store';
|
239 |
+
$field->foreign->field = 'store_id';
|
240 |
+
$field->foreign->on_update = 'cascade';
|
241 |
+
$field->foreign->on_delete = 'cascade';
|
242 |
+
$field->role = Mana_Db_Helper_Config::ROLE_STORE_SPECIFICS;
|
243 |
+
$field->default_formula = '{{= store.store_id }}';
|
244 |
+
$configHelper->propagateName($field);
|
245 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
246 |
+
|
247 |
+
$fieldName = 'primary_global_id';
|
248 |
+
$scope->fields->$fieldName->type = 'bigint';
|
249 |
+
$field = $scope->fields->$fieldName;
|
250 |
+
$field->foreign->entity = (string)$flattenedScopeXml->store_specifics_for;
|
251 |
+
$field->foreign->field = 'id';
|
252 |
+
$field->role = Mana_Db_Helper_Config::ROLE_FLAT;
|
253 |
+
$field->default_formula = '{{= global.primary.id }}';
|
254 |
+
$field->nullable = 1;
|
255 |
+
$configHelper->propagateName($field);
|
256 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
257 |
+
|
258 |
+
$fieldName = 'primary_id';
|
259 |
+
$scope->fields->$fieldName->type = 'bigint';
|
260 |
+
$field = $scope->fields->$fieldName;
|
261 |
+
$field->foreign->entity = (string)$scope->flattens;
|
262 |
+
$field->foreign->field = 'id';
|
263 |
+
$field->foreign->on_update = 'cascade';
|
264 |
+
$field->foreign->on_delete = 'cascade';
|
265 |
+
$field->role = Mana_Db_Helper_Config::ROLE_FLAT;
|
266 |
+
$field->default_formula = '{{= primary.id }}';
|
267 |
+
$field->nullable = 1;
|
268 |
+
$configHelper->propagateName($field);
|
269 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
270 |
+
|
271 |
+
$scope->unique->primary->global_id = '';
|
272 |
+
$scope->unique->primary->store_id = '';
|
273 |
+
}
|
274 |
+
else {
|
275 |
+
$fieldName = 'primary_id';
|
276 |
+
$scope->fields->$fieldName->type = 'bigint';
|
277 |
+
$field = $scope->fields->$fieldName;
|
278 |
+
$field->foreign->entity = (string)$scope->flattens;
|
279 |
+
$field->foreign->field = 'id';
|
280 |
+
$field->foreign->on_update = 'cascade';
|
281 |
+
$field->foreign->on_delete = 'cascade';
|
282 |
+
$field->role = Mana_Db_Helper_Config::ROLE_FLAT;
|
283 |
+
$field->default_formula = '{{= primary.id }}';
|
284 |
+
$field->nullable = 1;
|
285 |
+
$field->unique = 1;
|
286 |
+
$configHelper->propagateName($field);
|
287 |
+
$configHelper->propagateAttributes($scope, $field, array('module', 'version'));
|
288 |
+
}
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* @param Varien_Object $context
|
294 |
+
* @param Varien_Simplexml_Element $module
|
295 |
+
* @param Varien_Simplexml_Element $entity
|
296 |
+
* @param Varien_Simplexml_Element $scope
|
297 |
+
*/
|
298 |
+
public function _beginTableScript($context, $module, $entity, $scope) {
|
299 |
+
$context->setFields(array());
|
300 |
+
$context->setIndexes(array());
|
301 |
+
$context->setConstraints(array());
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* @param Varien_Object $context
|
306 |
+
* @param Varien_Simplexml_Element $module
|
307 |
+
* @param Varien_Simplexml_Element $entity
|
308 |
+
* @param Varien_Simplexml_Element $scope
|
309 |
+
* @param Varien_Simplexml_Element $field
|
310 |
+
*/
|
311 |
+
public function _fieldScript($context, $module, $entity, $scope, $field) {
|
312 |
+
if (((string)$field['module']) != $this->getModuleName() || ((string)$field['version']) != $this->getVersion()) {
|
313 |
+
return;
|
314 |
+
}
|
315 |
+
$fields = $context->getFields();
|
316 |
+
$fields[] = $field;
|
317 |
+
$context->setFields($fields);
|
318 |
+
|
319 |
+
if (isset($field->indexed) || isset($field->foreign) || !empty($field->primary)) {
|
320 |
+
$indexes = $context->getIndexes();
|
321 |
+
$indexes[] = $field;
|
322 |
+
$context->setIndexes($indexes);
|
323 |
+
}
|
324 |
+
|
325 |
+
if (isset($field->foreign)) {
|
326 |
+
$constraints = $context->getConstraints();
|
327 |
+
$constraints[] = $field;
|
328 |
+
$context->setConstraints($constraints);
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* @param Varien_Object $context
|
334 |
+
* @param Varien_Simplexml_Element $module
|
335 |
+
* @param Varien_Simplexml_Element $entity
|
336 |
+
* @param Varien_Simplexml_Element $scope
|
337 |
+
*/
|
338 |
+
public function _endTableScript($context, $module, $entity, $scope) {
|
339 |
+
$scope = $scope;
|
340 |
+
if (!empty($scope->unique)) {
|
341 |
+
/* @var $resource Mage_Core_Model_Mysql4_Resource */
|
342 |
+
$resource = Mage::getResourceSingleton('core/resource');
|
343 |
+
|
344 |
+
$indexes = $context->getIndexes();
|
345 |
+
foreach ($scope->unique->children() as $unique) {
|
346 |
+
$index = (object)array('unique' => 1, 'name' => 'unique_'.$unique->getName(), 'indexed_fields' => array());
|
347 |
+
$includeUniqueIndex = false;
|
348 |
+
foreach ($unique->children() as $field => $def) {
|
349 |
+
if (((string)$def['module']) == $this->getModuleName() && ((string)$def['version']) == $this->getVersion()) {
|
350 |
+
$includeUniqueIndex = true;
|
351 |
+
$index->indexed_fields[] = $field;
|
352 |
+
}
|
353 |
+
else {
|
354 |
+
$installedVersion = $resource->getDbVersion(((string)$def['module']).'_setup');
|
355 |
+
if ($installedVersion && version_compare($installedVersion, (string)$def['version']) >= 0) {
|
356 |
+
$index->indexed_fields[] = $field;
|
357 |
+
}
|
358 |
+
}
|
359 |
+
}
|
360 |
+
if ($includeUniqueIndex) {
|
361 |
+
if (!(((string)$scope->unique['module']) == $this->getModuleName() && ((string)$scope->unique['version']) == $this->getVersion())) {
|
362 |
+
$index->rebuild = true;
|
363 |
+
}
|
364 |
+
$indexes[] = $index;
|
365 |
+
}
|
366 |
+
}
|
367 |
+
$context->setIndexes($indexes);
|
368 |
+
}
|
369 |
+
|
370 |
+
$sql = $context->getSql();
|
371 |
+
$context->setTable(
|
372 |
+
$this->getTable(((string)$module->name) . '/' .
|
373 |
+
((string)$entity->name) . '/' .
|
374 |
+
((string)$scope->name)));
|
375 |
+
if (((string)$scope['module']) != $this->getModuleName() || ((string)$scope['version']) != $this->getVersion()) {
|
376 |
+
foreach ($context->getFields() as $field) {
|
377 |
+
$sql .= "ALTER TABLE `{$context->getTable()}` ADD COLUMN ( ";
|
378 |
+
$sql .= $this->_renderField($field);
|
379 |
+
$sql .= ");\n";
|
380 |
+
}
|
381 |
+
foreach ($context->getIndexes() as $index) {
|
382 |
+
if (!empty($index->rebuild)) {
|
383 |
+
$sql .= "ALTER TABLE `{$context->getTable()}` DROP KEY `".(string)$index->name."`";
|
384 |
+
$sql .= ";\n";
|
385 |
+
}
|
386 |
+
$sql .= "ALTER TABLE `{$context->getTable()}` ADD ";
|
387 |
+
$sql .= $this->_renderIndex($index);
|
388 |
+
$sql .= ";\n";
|
389 |
+
}
|
390 |
+
}
|
391 |
+
else {
|
392 |
+
if (count($context->getFields()) || count($context->getIndexes())) {
|
393 |
+
$sql .= "DROP TABLE IF EXISTS `{$context->getTable()}`;\n";
|
394 |
+
$sql .= "CREATE TABLE `{$context->getTable()}` ( \n";
|
395 |
+
$sep = false;
|
396 |
+
foreach ($context->getFields() as $field) {
|
397 |
+
if ($sep) $sql .= ", \n"; else $sep = true;
|
398 |
+
$sql .= " ".$this->_renderField($field);
|
399 |
+
}
|
400 |
+
foreach ($context->getIndexes() as $index) {
|
401 |
+
if ($sep) $sql .= ", \n"; else $sep = true;
|
402 |
+
$sql .= " " .$this->_renderIndex($index);
|
403 |
+
}
|
404 |
+
$sql .= "\n";
|
405 |
+
$sql .= ") ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='';\n";
|
406 |
+
}
|
407 |
+
}
|
408 |
+
foreach ($context->getConstraints() as $constraint) {
|
409 |
+
$sql .= "ALTER TABLE `{$context->getTable()}` ADD CONSTRAINT ";
|
410 |
+
$sql .= $this->_renderConstraint($context, $constraint);
|
411 |
+
$sql .= ";\n";
|
412 |
+
}
|
413 |
+
|
414 |
+
$context->setSql($sql);
|
415 |
+
}
|
416 |
+
|
417 |
+
protected function _renderField($field) {
|
418 |
+
$sql = '';
|
419 |
+
$sql .= "`".((string)$field->name)."` ";
|
420 |
+
$sql .= ((string)$field->type) ." ";
|
421 |
+
if (isset($field->nullable)) {
|
422 |
+
$sql .= "null ";
|
423 |
+
}
|
424 |
+
else {
|
425 |
+
$sql .= "NOT null ";
|
426 |
+
if (!empty($field->default_value) && strpos(strtolower((string)$field->type), 'text') === false) {
|
427 |
+
$sql .= "DEFAULT '".((string)$field->default_value)."' ";
|
428 |
+
}
|
429 |
+
elseif (strpos((string)$field->type, 'varchar') !== false) {
|
430 |
+
$sql .= "DEFAULT '' ";
|
431 |
+
}
|
432 |
+
}
|
433 |
+
if (!empty($field->primary)) {
|
434 |
+
$sql .= "AUTO_INCREMENT ";
|
435 |
+
}
|
436 |
+
return $sql;
|
437 |
+
}
|
438 |
+
|
439 |
+
protected function _renderIndex($field) {
|
440 |
+
$sql = '';
|
441 |
+
if (!empty($field->primary)) {
|
442 |
+
$sql .= "PRIMARY KEY ";
|
443 |
+
}
|
444 |
+
elseif (!empty($field->unique)) {
|
445 |
+
$sql .= "UNIQUE KEY `" . ((string)$field->name) . "` ";
|
446 |
+
}
|
447 |
+
else {
|
448 |
+
$sql .= "KEY `" . ((string)$field->name) . "` ";
|
449 |
+
}
|
450 |
+
if (empty($field->indexed_fields)) {
|
451 |
+
$sql .= "(`" . ((string)$field->name) . "`) ";
|
452 |
+
}
|
453 |
+
else {
|
454 |
+
$indexedFields = array();
|
455 |
+
foreach ($field->indexed_fields as $indexedField) {
|
456 |
+
$indexedFields[] = "`$indexedField`";
|
457 |
+
}
|
458 |
+
$sql .= "(" . implode(', ', $indexedFields) . ") ";
|
459 |
+
}
|
460 |
+
|
461 |
+
return $sql;
|
462 |
+
}
|
463 |
+
|
464 |
+
protected function _renderConstraint($context, $field) {
|
465 |
+
$sql = '';
|
466 |
+
$sql .= "`FK_{$context->getTable()}_". ((string)$field->name)."` ";
|
467 |
+
$sql .= "FOREIGN KEY (`" . ((string)$field->name). "`) ";
|
468 |
+
$sql .= "REFERENCES `{$this->getTable((string)$field->foreign->entity)}` (`".((string)$field->foreign->field)."`) ";
|
469 |
+
if (!empty($field->foreign->on_delete)) {
|
470 |
+
$sql .= "ON DELETE " . ((string)$field->foreign->on_delete) . " ";
|
471 |
+
}
|
472 |
+
if (!empty($field->foreign->on_update)) {
|
473 |
+
$sql .= "ON UPDATE ".((string)$field->foreign->on_update)." ";
|
474 |
+
}
|
475 |
+
|
476 |
+
return $sql;
|
477 |
+
}
|
478 |
+
}
|
app/code/local/Mana/Db/Resource/Edit/Session.php
CHANGED
@@ -45,4 +45,15 @@ class Mana_Db_Resource_Edit_Session extends Mage_Core_Model_Mysql4_Abstract {//M
|
|
45 |
throw $e;
|
46 |
}
|
47 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
}
|
45 |
throw $e;
|
46 |
}
|
47 |
}
|
48 |
+
|
49 |
+
public function isExpired($editSessionId) {
|
50 |
+
$db = $this->_getReadAdapter();
|
51 |
+
$table = Mage::getSingleton('core/resource')->getTableName('mana_db/edit_session');
|
52 |
+
|
53 |
+
$select = $db->select()
|
54 |
+
->from($table, 'id')
|
55 |
+
->where("id = ?", $editSessionId);
|
56 |
+
|
57 |
+
return $db->fetchOne($select) ? false : true;
|
58 |
+
}
|
59 |
}
|
app/code/local/Mana/Db/Resource/Entity.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getScopeName()
|
11 |
+
*
|
12 |
+
*/
|
13 |
+
class Mana_Db_Resource_Entity extends Mage_Core_Model_Mysql4_Abstract {
|
14 |
+
protected $_scope;
|
15 |
+
|
16 |
+
public function __construct($data = null) {
|
17 |
+
if (is_array($data)) {
|
18 |
+
if (isset($data['scope'])) {
|
19 |
+
$this->_scope = $data['scope'];
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
parent::__construct();
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param Mana_Db_Model_Entity $object
|
28 |
+
* @param int $id
|
29 |
+
* @param int $storeId
|
30 |
+
* @param string $fieldName
|
31 |
+
* @return Mana_Db_Resource_Entity
|
32 |
+
*/
|
33 |
+
public function loadForStore($object, $id, $storeId, $fieldName) {
|
34 |
+
$read = $this->_getReadAdapter();
|
35 |
+
$select = $this->_getReadAdapter()->select()
|
36 |
+
->from($this->getMainTable())
|
37 |
+
->where("{$this->getMainTable()}.`$fieldName` = ?", $id)
|
38 |
+
->where("{$this->getMainTable()}.`store_id` = ?", $storeId);
|
39 |
+
$data = $read->fetchRow($select);
|
40 |
+
|
41 |
+
if ($data) {
|
42 |
+
$object->setData($data);
|
43 |
+
}
|
44 |
+
|
45 |
+
$this->unserializeFields($object);
|
46 |
+
$this->_afterLoad($object);
|
47 |
+
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
protected function _construct() {
|
52 |
+
$this->_initScope();
|
53 |
+
}
|
54 |
+
protected function _initScope() {
|
55 |
+
|
56 |
+
/* @var $db Mana_Db_Helper_Data */
|
57 |
+
$db = Mage::helper('mana_db');
|
58 |
+
|
59 |
+
$this->_init($db->getScopedName($this->_scope), 'id');
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @param Mana_Db_Model_Entity $object
|
65 |
+
* @param int $id
|
66 |
+
* @param int $sessionId
|
67 |
+
* @return Mana_Db_Resource_Entity
|
68 |
+
*/
|
69 |
+
public function loadEdited($object, $id, $sessionId) {
|
70 |
+
$read = $this->_getReadAdapter();
|
71 |
+
$select = $read->select()
|
72 |
+
->from($this->getMainTable())
|
73 |
+
->where("{$this->getMainTable()}.`edit_status` = ?", $id)
|
74 |
+
->where("{$this->getMainTable()}.`edit_session_id` = ?", $sessionId);
|
75 |
+
$data = $read->fetchRow($select);
|
76 |
+
|
77 |
+
if ($data) {
|
78 |
+
$object->setData($data);
|
79 |
+
}
|
80 |
+
|
81 |
+
$this->unserializeFields($object);
|
82 |
+
$this->_afterLoad($object);
|
83 |
+
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
}
|
app/code/local/Mana/Db/Resource/Entity/Collection.php
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getScopeName()
|
11 |
+
*/
|
12 |
+
class Mana_Db_Resource_Entity_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
|
13 |
+
protected $_scope;
|
14 |
+
protected $_editFilter = null;
|
15 |
+
protected $_parentCondition = '';
|
16 |
+
|
17 |
+
public function __construct($resource = null) {
|
18 |
+
if (is_array($resource)) {
|
19 |
+
if (isset($resource['scope'])) {
|
20 |
+
$this->_scope = $resource['scope'];
|
21 |
+
}
|
22 |
+
$resource = isset($resource['resource']) ? $resource['resource'] : null;
|
23 |
+
}
|
24 |
+
|
25 |
+
parent::__construct($resource);
|
26 |
+
}
|
27 |
+
|
28 |
+
protected function _construct() {
|
29 |
+
$this->_initScope();
|
30 |
+
}
|
31 |
+
protected function _initScope() {
|
32 |
+
|
33 |
+
/* @var $db Mana_Db_Helper_Data */
|
34 |
+
$db = Mage::helper('mana_db');
|
35 |
+
|
36 |
+
$this->_init($this->_scope);
|
37 |
+
return $this;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Get resource instance
|
42 |
+
*
|
43 |
+
* @return Mage_Core_Model_Mysql4_Abstract
|
44 |
+
*/
|
45 |
+
public function getResource() {
|
46 |
+
if (empty($this->_resource)) {
|
47 |
+
/* @var $db Mana_Db_Helper_Data */
|
48 |
+
$db = Mage::helper('mana_db');
|
49 |
+
|
50 |
+
$this->_resource = $db->getResourceSingleton($this->getResourceModelName());
|
51 |
+
}
|
52 |
+
|
53 |
+
return $this->_resource;
|
54 |
+
}
|
55 |
+
|
56 |
+
public function getNewEmptyItem() {
|
57 |
+
/* @var $db Mana_Db_Helper_Data */
|
58 |
+
$db = Mage::helper('mana_db');
|
59 |
+
|
60 |
+
return $db->getModel($this->_model);
|
61 |
+
}
|
62 |
+
|
63 |
+
public function setEditFilter($editFilter, $parentCondition = '') {
|
64 |
+
$this->_editFilter = $editFilter;
|
65 |
+
$this->_parentCondition = $parentCondition;
|
66 |
+
|
67 |
+
return $this;
|
68 |
+
}
|
69 |
+
|
70 |
+
public function setStoreFilter($storeId = null) {
|
71 |
+
if ($storeId === null) {
|
72 |
+
$storeId = Mage::app()->getStore()->getId();
|
73 |
+
}
|
74 |
+
|
75 |
+
$this->getSelect()->where("`main_table`.`store_id` = ?", $storeId);
|
76 |
+
return $this;
|
77 |
+
}
|
78 |
+
|
79 |
+
protected function _beforeLoad() {
|
80 |
+
$this->_renderEditFilter();
|
81 |
+
parent::_beforeLoad();
|
82 |
+
|
83 |
+
return $this;
|
84 |
+
}
|
85 |
+
|
86 |
+
protected function _renderEditFilter($select = null) {
|
87 |
+
if (!$select) {
|
88 |
+
$select = $this->getSelect();
|
89 |
+
}
|
90 |
+
$alias = 'main_table';
|
91 |
+
if (is_array($this->_editFilter)) {
|
92 |
+
$sql = count($this->_editFilter['saved'])
|
93 |
+
? $this->getConnection()->quoteInto("$alias.edit_status = 0 AND $alias.id NOT IN (?)", array_keys($this->_editFilter['saved']))
|
94 |
+
: "$alias.edit_status = 0";
|
95 |
+
if ($this->_parentCondition) {
|
96 |
+
$sql .= " AND ($alias.{$this->_parentCondition})";
|
97 |
+
}
|
98 |
+
if (count($this->_editFilter['saved'])) {
|
99 |
+
$sql = "($sql) OR ({$this->getConnection()->quoteInto(
|
100 |
+
"$alias.edit_status <> 0 AND $alias.edit_session_id = ?", $this->_editFilter['sessionId'])})";
|
101 |
+
}
|
102 |
+
if (count($this->_editFilter['deleted'])) {
|
103 |
+
$sql = "($sql)" .
|
104 |
+
" AND ({$this->getConnection()->quoteInto("$alias.id NOT IN (?)", $this->_editFilter['deleted'])})";
|
105 |
+
//" AND ({$this->getConnection()->quoteInto("$alias.edit_status NOT IN (?)", $this->_editFilter['deleted'])})";
|
106 |
+
}
|
107 |
+
$select->where($sql);
|
108 |
+
}
|
109 |
+
elseif ($this->_editFilter) {
|
110 |
+
$select->where("$alias.edit_status = 0");
|
111 |
+
if ($this->_parentCondition) {
|
112 |
+
$select->where("$alias.{$this->_parentCondition}");
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
return $this;
|
117 |
+
}
|
118 |
+
|
119 |
+
public function getSelectCountSql() {
|
120 |
+
$sql = parent::getSelectCountSql();
|
121 |
+
$this->_renderEditFilter($sql);
|
122 |
+
return $sql;
|
123 |
+
}
|
124 |
+
}
|
app/code/local/Mana/Db/Resource/Entity/Indexer.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
|
13 |
+
class Mana_Db_Resource_Entity_Indexer extends Mage_Core_Model_Mysql4_Abstract {
|
14 |
+
/**
|
15 |
+
* Resource initialization
|
16 |
+
*/
|
17 |
+
protected function _construct() {
|
18 |
+
$this->_setResource('core');
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param Mana_Db_Model_Entity_Indexer $indexer provides access to process record and indexer setup
|
23 |
+
* @param Varien_Simplexml_Element $target setup in config.xml
|
24 |
+
* @param Varien_Simplexml_Element $scope setup in m_db.xml
|
25 |
+
* @param array $options on which records to run
|
26 |
+
* @return void
|
27 |
+
*/
|
28 |
+
public function flattenScope($indexer, $target, $scope, $options) {
|
29 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
30 |
+
$targetEntity = ((string)$target->entity) . '/' . $scope->getName();
|
31 |
+
|
32 |
+
if (isset($options['entity_filters']) && !isset($options['entity_filters'][$targetEntity])) {
|
33 |
+
return;
|
34 |
+
}
|
35 |
+
$options = array_merge(array(
|
36 |
+
'provide_field_details_in_exceptions' => true,
|
37 |
+
), $options);
|
38 |
+
if (isset($options['entity_filters']) && !isset($options['entity_filter_formula'])) {
|
39 |
+
$options['entity_filter_formula'] = '{{= ' . $options['entity_filters'][$targetEntity] . '}}';
|
40 |
+
}
|
41 |
+
$db = $this->_getWriteAdapter();
|
42 |
+
/* @var $res Mage_Core_Model_Resource */
|
43 |
+
$res = Mage::getSingleton('core/resource');
|
44 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
45 |
+
$dbHelper = Mage::helper('mana_db');
|
46 |
+
/* @var $formulaHelper Mana_Db_Helper_Formula */
|
47 |
+
$formulaHelper = Mage::helper('mana_db/formula');
|
48 |
+
|
49 |
+
|
50 |
+
// get basic select from all source tables, properly joined (based on m_db.xml)
|
51 |
+
/** @noinspection PhpUndefinedFieldInspection */
|
52 |
+
$entity = (string)$scope->flattens;
|
53 |
+
//$db->query($formulaHelper->delete($entity, $targetEntity));
|
54 |
+
|
55 |
+
// get formula hashes and formula texts
|
56 |
+
$formulaGroups = $formulaHelper->getFormulaGroups($targetEntity, $options);
|
57 |
+
|
58 |
+
// for each formula hash => formula text
|
59 |
+
foreach ($formulaGroups as $formulas) {
|
60 |
+
$formulas = $formulas ? json_decode($formulas, true) : array();
|
61 |
+
|
62 |
+
// filter basic select by formula hash
|
63 |
+
$context = $formulaHelper->select($targetEntity, $formulas, $options);
|
64 |
+
|
65 |
+
// convert SELECT into UPDATE which acts as INSERT on DUPLICATE unique keys
|
66 |
+
$sql = $context->getSelect()->insertFromSelect(
|
67 |
+
$res->getTableName($dbHelper->getScopedName($targetEntity)),
|
68 |
+
$context->getFields());
|
69 |
+
|
70 |
+
// run the statement
|
71 |
+
try {
|
72 |
+
$db->query($sql);
|
73 |
+
}
|
74 |
+
catch (Exception $e) {
|
75 |
+
/* @var $logger Mana_Core_Helper_Logger */
|
76 |
+
$logger = Mage::helper('mana_core/logger');
|
77 |
+
$logger->logDbIndexerFailure($sql);
|
78 |
+
throw $e;
|
79 |
+
}
|
80 |
+
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
protected function _getUpdateSelect($basicSelect, $formulaHash) {
|
85 |
+
$select = clone $basicSelect;
|
86 |
+
|
87 |
+
return $select;
|
88 |
+
}
|
89 |
+
}
|
app/code/local/Mana/Db/Resource/Entity/JsonCollection.php
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
* @method string getScopeName()
|
11 |
+
*/
|
12 |
+
class Mana_Db_Resource_Entity_JsonCollection extends Varien_Data_Collection {
|
13 |
+
protected $_rawData = array();
|
14 |
+
protected $_data = array();
|
15 |
+
protected $_mFilters = array();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param $data
|
19 |
+
* @return Mana_Db_Resource_Entity_JsonCollection
|
20 |
+
*/
|
21 |
+
public function setData($data) {
|
22 |
+
foreach (array_keys($data) as $index) {
|
23 |
+
if (!isset($data[$index]['id'])) {
|
24 |
+
$data[$index]['id'] = $index;
|
25 |
+
}
|
26 |
+
}
|
27 |
+
$this->_data = $data;
|
28 |
+
$this->_rawData = $data;
|
29 |
+
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function getData() {
|
34 |
+
return $this->_data;
|
35 |
+
}
|
36 |
+
public function load($printQuery = false, $logQuery = false) {
|
37 |
+
if ($this->isLoaded()) {
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
+
|
41 |
+
$this->_beforeLoad();
|
42 |
+
|
43 |
+
$this->_renderFilters()
|
44 |
+
->_renderOrders()
|
45 |
+
->_renderLimit();
|
46 |
+
|
47 |
+
$data = $this->getData();
|
48 |
+
|
49 |
+
if (is_array($data)) {
|
50 |
+
foreach ($data as $row) {
|
51 |
+
$item = $this->getNewEmptyItem();
|
52 |
+
$item->addData($row);
|
53 |
+
$this->addItem($item);
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
$this->_setIsLoaded();
|
58 |
+
$this->_afterLoad();
|
59 |
+
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
|
63 |
+
protected function _beforeLoad() {
|
64 |
+
return $this;
|
65 |
+
}
|
66 |
+
|
67 |
+
protected function _afterLoad() {
|
68 |
+
return $this;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @return Mana_Db_Resource_Entity_JsonCollection
|
73 |
+
*/
|
74 |
+
protected function _renderFilters() {
|
75 |
+
$this->_data = array_filter($this->_data, array($this, '_filterItem'));
|
76 |
+
return $this;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Render sql select orders
|
81 |
+
*
|
82 |
+
* @return Mana_Db_Resource_Entity_JsonCollection
|
83 |
+
*/
|
84 |
+
protected function _renderOrders() {
|
85 |
+
if (count($this->_orders)) {
|
86 |
+
uasort($this->_data, array($this, '_compareItems'));
|
87 |
+
}
|
88 |
+
|
89 |
+
return $this;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Render sql select limit
|
94 |
+
*
|
95 |
+
* @return Mana_Db_Resource_Entity_JsonCollection
|
96 |
+
*/
|
97 |
+
protected function _renderLimit() {
|
98 |
+
if ($this->_pageSize !== false) {
|
99 |
+
$offset = ($this->_curPage - 1) * $this->_pageSize;
|
100 |
+
$count = count($this->_data);
|
101 |
+
if ($count > $offset) {
|
102 |
+
if ($count >= $offset + $this->_pageSize) {
|
103 |
+
$this->_data = array_slice($this->_data, $offset, $this->_pageSize);
|
104 |
+
}
|
105 |
+
else {
|
106 |
+
$this->_data = array_slice($this->_data, $offset);
|
107 |
+
}
|
108 |
+
}
|
109 |
+
else {
|
110 |
+
$this->_data = array();
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
return $this;
|
115 |
+
}
|
116 |
+
|
117 |
+
public function getRawData() {
|
118 |
+
return $this->_rawData;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @param array $a
|
123 |
+
* @param array $b
|
124 |
+
* @return int
|
125 |
+
*/
|
126 |
+
protected function _compareItems($a, $b) {
|
127 |
+
foreach ($this->_orders as $column => $direction) {
|
128 |
+
if (isset($a[$column])) {
|
129 |
+
if (isset($b[$column])) {
|
130 |
+
if ($a[$column] < $b[$column]) {
|
131 |
+
return strtolower($direction) == 'desc' ? 1 : -1;
|
132 |
+
}
|
133 |
+
if ($a[$column] > $b[$column]) {
|
134 |
+
return strtolower($direction) == 'desc' ? -1 : 1;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
else {
|
138 |
+
return strtolower($direction) == 'desc' ? -1 : 1;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
else {
|
142 |
+
if (isset($b[$column])) {
|
143 |
+
return strtolower($direction) == 'desc' ? 1 : -1;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
}
|
147 |
+
return 0;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* @param array $a
|
152 |
+
* @return bool
|
153 |
+
*/
|
154 |
+
protected function _filterItem($a) {
|
155 |
+
foreach ($this->_mFilters as $filter) {
|
156 |
+
$value = isset($a[$filter['attribute']]) ? $a[$filter['attribute']] : '';
|
157 |
+
if (isset($filter['condition']['like'])) {
|
158 |
+
$test = $filter['condition']['like'];
|
159 |
+
if ($this->getMbstring()->stripos($value, $this->getMbstring()->substr($test, 1, mb_strlen($test) - 2)) === false) {
|
160 |
+
return false;
|
161 |
+
}
|
162 |
+
}
|
163 |
+
elseif (isset($filter['condition']['eq'])) {
|
164 |
+
$test = $filter['condition']['eq'];
|
165 |
+
if ($value != $test) {
|
166 |
+
return false;
|
167 |
+
}
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
return true;
|
172 |
+
}
|
173 |
+
public function addFieldToFilter($attribute, $condition = null) {
|
174 |
+
$this->_mFilters[] = array('attribute' => $attribute, 'condition' => $condition);
|
175 |
+
}
|
176 |
+
|
177 |
+
#region Dependencies
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @return Mana_Core_Helper_Mbstring
|
181 |
+
*/
|
182 |
+
public function getMbstring() {
|
183 |
+
return Mage::helper('mana_core/mbstring');
|
184 |
+
}
|
185 |
+
#endregion
|
186 |
+
}
|
app/code/local/Mana/Db/Resource/Formula.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Db
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Db_Resource_Formula extends Mage_Core_Model_Mysql4_Abstract {
|
13 |
+
/**
|
14 |
+
* Resource initialization
|
15 |
+
*/
|
16 |
+
protected function _construct() {
|
17 |
+
$this->_setResource('core');
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param Mana_Db_Model_Formula_Context $context
|
22 |
+
* @param Mana_Db_Model_Formula_Expr $expr
|
23 |
+
* @return Varien_Db_Select
|
24 |
+
*/
|
25 |
+
public function getAggregateSubSelect($context, $expr) {
|
26 |
+
/* @var $db Varien_Db_Adapter_Pdo_Mysql */
|
27 |
+
$db = $this->getReadConnection();
|
28 |
+
|
29 |
+
$select = $db->select();
|
30 |
+
throw new Exception('Not implemented');
|
31 |
+
}
|
32 |
+
|
33 |
+
public function getTableFields($entity) {
|
34 |
+
/* @var $dbHelper Mana_Db_Helper_Data */
|
35 |
+
$dbHelper = Mage::helper('mana_db');
|
36 |
+
|
37 |
+
return $this->getReadConnection()->describeTable($this->getTable($dbHelper->getScopedName($entity)));
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return Varien_Db_Select
|
42 |
+
*/
|
43 |
+
public function select() {
|
44 |
+
/* @var $db Varien_Db_Adapter_Pdo_Mysql */
|
45 |
+
$db = $this->getReadConnection();
|
46 |
+
|
47 |
+
return $db->select();
|
48 |
+
}
|
49 |
+
|
50 |
+
}
|
app/code/local/Mana/Db/etc/config.xml
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
<Mana_Db>
|
13 |
<!-- This version number identifies version of database tables specific to this extension. It is written to
|
14 |
core_resource table. -->
|
15 |
-
<version>
|
16 |
</Mana_Db>
|
17 |
</modules>
|
18 |
<!-- This section contains module settings which are merged into global configuration during each page load,
|
@@ -72,6 +72,12 @@
|
|
72 |
<mana_db_replicator>
|
73 |
<model>mana_db/indexer</model>
|
74 |
</mana_db_replicator>
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
</indexer>
|
76 |
</index>
|
77 |
<!-- BASED ON SNIPPET: New Models/Event support (config.xml) -->
|
@@ -138,7 +144,7 @@
|
|
138 |
<observers>
|
139 |
<mana_db>
|
140 |
<class>mana_db/observer</class> <!-- model name of class containing event handler methods -->
|
141 |
-
<method>
|
142 |
</mana_db>
|
143 |
</observers>
|
144 |
</model_save_commit_after>
|
12 |
<Mana_Db>
|
13 |
<!-- This version number identifies version of database tables specific to this extension. It is written to
|
14 |
core_resource table. -->
|
15 |
+
<version>13.09.25.14</version>
|
16 |
</Mana_Db>
|
17 |
</modules>
|
18 |
<!-- This section contains module settings which are merged into global configuration during each page load,
|
72 |
<mana_db_replicator>
|
73 |
<model>mana_db/indexer</model>
|
74 |
</mana_db_replicator>
|
75 |
+
<mana_db translate="name description" module="mana_db">
|
76 |
+
<model>mana_db/entity_indexer</model>
|
77 |
+
<name>Entity Flat Data (MANAdev)</name>
|
78 |
+
<description>Reorganizes entity data to flat structure</description>
|
79 |
+
<targets/>
|
80 |
+
</mana_db>
|
81 |
</indexer>
|
82 |
</index>
|
83 |
<!-- BASED ON SNIPPET: New Models/Event support (config.xml) -->
|
144 |
<observers>
|
145 |
<mana_db>
|
146 |
<class>mana_db/observer</class> <!-- model name of class containing event handler methods -->
|
147 |
+
<method>afterSaveCommit</method> <!-- event handler method name -->
|
148 |
</mana_db>
|
149 |
</observers>
|
150 |
</model_save_commit_after>
|
app/code/local/Mana/Db/etc/m_db.xml
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
@category Mana
|
4 |
+
@package Mana_Db
|
5 |
+
@copyright Copyright (c) http://www.manadev.com
|
6 |
+
@license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
-->
|
8 |
+
<!-- BASED ON SNIPPET: New Module/etc/config.xml -->
|
9 |
+
<config>
|
10 |
+
<modules>
|
11 |
+
<eav>
|
12 |
+
<tables>
|
13 |
+
<attribute_option>
|
14 |
+
<fields>
|
15 |
+
<global_label>
|
16 |
+
<formula>
|
17 |
+
<expr>{{= value.value }}</expr>
|
18 |
+
<join>
|
19 |
+
<value>
|
20 |
+
<type>left</type>
|
21 |
+
<entity>eav/attribute_option_value</entity>
|
22 |
+
<on>{{= value.option_id }} = {{= context.option_id }} AND {{= value.store_id }} = 0</on>
|
23 |
+
</value>
|
24 |
+
</join>
|
25 |
+
</formula>
|
26 |
+
</global_label>
|
27 |
+
<store_label>
|
28 |
+
<formula>
|
29 |
+
<expr>{{= value.value }}</expr>
|
30 |
+
<join>
|
31 |
+
<value>
|
32 |
+
<type>left</type>
|
33 |
+
<entity>eav/attribute_option_value</entity>
|
34 |
+
<on>{{= value.option_id }} = {{= context.option_id }} AND {{= value.store_id }} = {{= store.store_id }}</on>
|
35 |
+
</value>
|
36 |
+
</join>
|
37 |
+
</formula>
|
38 |
+
</store_label>
|
39 |
+
</fields>
|
40 |
+
</attribute_option>
|
41 |
+
</tables>
|
42 |
+
</eav>
|
43 |
+
</modules>
|
44 |
+
</config>
|
app/code/local/Mana/Filters/Block/Filter.php
CHANGED
@@ -9,6 +9,8 @@
|
|
9 |
* Block type for showing options for filter based on custom attribute
|
10 |
* @author Mana Team
|
11 |
* Injected into layout instead of standard catalog/layer_filter_attribute in Mana_Filters_Block_View_Category::_initBlocks.
|
|
|
|
|
12 |
*/
|
13 |
class Mana_Filters_Block_Filter extends Mage_Catalog_Block_Layer_Filter_Abstract {
|
14 |
protected $_isBlockPrepared = false;
|
@@ -66,17 +68,36 @@ class Mana_Filters_Block_Filter extends Mage_Catalog_Block_Layer_Filter_Abstract
|
|
66 |
foreach ($this->getItems() as $item) {
|
67 |
/* @var $item Mana_Filters_Model_Item */
|
68 |
if ($item->getMSelected()) {
|
69 |
-
$result[] = $item->
|
70 |
}
|
71 |
}
|
72 |
-
|
|
|
73 |
}
|
74 |
|
|
|
|
|
|
|
|
|
75 |
public function getItemsCount() {
|
76 |
$this->_prepareFilterBlockOnce();
|
77 |
return $this->getHidden() ? 0 : $this->_filter->getItemsCount();
|
78 |
}
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
protected function _initFilter() {
|
81 |
if ($filter = Mage::getSingleton('mana_filters/repository')->getFilter($this->getFilterOptions()->getCode())) {
|
82 |
$this->_filter = $filter;
|
@@ -103,4 +124,31 @@ class Mana_Filters_Block_Filter extends Mage_Catalog_Block_Layer_Filter_Abstract
|
|
103 |
}
|
104 |
return $this;
|
105 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
}
|
9 |
* Block type for showing options for filter based on custom attribute
|
10 |
* @author Mana Team
|
11 |
* Injected into layout instead of standard catalog/layer_filter_attribute in Mana_Filters_Block_View_Category::_initBlocks.
|
12 |
+
*
|
13 |
+
* @method Mana_Filters_Model_Filter2_Store getFilterOptions()
|
14 |
*/
|
15 |
class Mana_Filters_Block_Filter extends Mage_Catalog_Block_Layer_Filter_Abstract {
|
16 |
protected $_isBlockPrepared = false;
|
68 |
foreach ($this->getItems() as $item) {
|
69 |
/* @var $item Mana_Filters_Model_Item */
|
70 |
if ($item->getMSelected()) {
|
71 |
+
$result[$item->getSeoValue()] = $item->getSeoData();
|
72 |
}
|
73 |
}
|
74 |
+
|
75 |
+
return $this->jsonHelper()->encodeAttribute($result);
|
76 |
}
|
77 |
|
78 |
+
public function getPopupBlockName() {
|
79 |
+
$displayOptions = $this->getFilterOptions()->getDisplayOptions();
|
80 |
+
return (string)$displayOptions->popup_class;
|
81 |
+
}
|
82 |
public function getItemsCount() {
|
83 |
$this->_prepareFilterBlockOnce();
|
84 |
return $this->getHidden() ? 0 : $this->_filter->getItemsCount();
|
85 |
}
|
86 |
|
87 |
+
public function getMultipleValueSeparator() {
|
88 |
+
if (((string)Mage::getConfig()->getNode('modules/ManaPro_FilterSeoLinks/active')) == 'true') {
|
89 |
+
/* @var $seo Mana_Seo_Helper_Data */
|
90 |
+
$seo = Mage::helper('mana_seo');
|
91 |
+
|
92 |
+
$schema = $seo->getActiveSchema(Mage::app()->getStore()->getId());
|
93 |
+
|
94 |
+
return $schema->getMultipleValueSeparator();
|
95 |
+
}
|
96 |
+
else {
|
97 |
+
return '_';
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
protected function _initFilter() {
|
102 |
if ($filter = Mage::getSingleton('mana_filters/repository')->getFilter($this->getFilterOptions()->getCode())) {
|
103 |
$this->_filter = $filter;
|
124 |
}
|
125 |
return $this;
|
126 |
}
|
127 |
+
|
128 |
+
public function getListItemClass($item) {
|
129 |
+
$result = '';
|
130 |
+
if ($item->getMShowSelected()) {
|
131 |
+
$result .= 'm-selected-ln-item';
|
132 |
+
}
|
133 |
+
if (!($item->getCount() || $item->getMSelected())) {
|
134 |
+
if ($result) {
|
135 |
+
$result .= ' ';
|
136 |
+
}
|
137 |
+
$result .= 'm-disabled';
|
138 |
+
}
|
139 |
+
if ($result) {
|
140 |
+
$result = "class=\"$result\"";
|
141 |
+
}
|
142 |
+
return $result;
|
143 |
+
}
|
144 |
+
|
145 |
+
#region Dependencies
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @return Mana_Core_Helper_Json
|
149 |
+
*/
|
150 |
+
public function jsonHelper() {
|
151 |
+
return Mage::helper('mana_core/json');
|
152 |
+
}
|
153 |
+
#endregion
|
154 |
}
|
app/code/local/Mana/Filters/Block/View.php
CHANGED
@@ -29,7 +29,7 @@ class Mana_Filters_Block_View extends Mage_Catalog_Block_Layer_View {
|
|
29 |
{
|
30 |
/* @var $layoutHelper Mana_Core_Helper_Layout */
|
31 |
$layoutHelper = Mage::helper('mana_core/layout');
|
32 |
-
$layoutHelper->delayPrepareLayout($this,
|
33 |
|
34 |
return $this;
|
35 |
}
|
@@ -52,7 +52,7 @@ class Mana_Filters_Block_View extends Mage_Catalog_Block_Layer_View {
|
|
52 |
|
53 |
$showState = 'all';
|
54 |
if ($showInFilter = $this->getShowInFilter()) {
|
55 |
-
if ($template = Mage::getStoreConfig('mana_filters/positioning/' . $showInFilter)) {
|
56 |
$this->setTemplate($template);
|
57 |
}
|
58 |
$showState = Mage::getStoreConfig('mana_filters/positioning/show_state_' . $showInFilter);
|
@@ -81,7 +81,7 @@ class Mana_Filters_Block_View extends Mage_Catalog_Block_Layer_View {
|
|
81 |
'query' => $query,
|
82 |
'layer' => $layer,
|
83 |
'attribute_model' => $filterOptions->getAttribute(),
|
84 |
-
'mode' => $
|
85 |
));
|
86 |
$block->init();
|
87 |
$this->setChild($filterOptions->getCode() . '_filter', $block);
|
@@ -94,6 +94,17 @@ class Mana_Filters_Block_View extends Mage_Catalog_Block_Layer_View {
|
|
94 |
return $this;
|
95 |
}
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
public function getFilters() {
|
98 |
/* @var $helper Mana_Filters_Helper_Data */
|
99 |
$helper = Mage::helper(strtolower('Mana_Filters'));
|
@@ -125,14 +136,14 @@ class Mana_Filters_Block_View extends Mage_Catalog_Block_Layer_View {
|
|
125 |
/* @var $helper Mana_Filters_Helper_Data */
|
126 |
$helper = Mage::helper(strtolower('Mana_Filters'));
|
127 |
|
128 |
-
return $helper->getLayer();
|
129 |
}
|
130 |
|
131 |
public function canShowBlock() {
|
132 |
/* @var $helper Mana_Filters_Helper_Data */
|
133 |
$helper = Mage::helper(strtolower('Mana_Filters'));
|
134 |
|
135 |
-
switch ($
|
136 |
case 'category':
|
137 |
return $this->_canShowBlockInCategory();
|
138 |
case 'search':
|
@@ -153,16 +164,29 @@ class Mana_Filters_Block_View extends Mage_Catalog_Block_Layer_View {
|
|
153 |
}
|
154 |
}
|
155 |
public function _canShowBlockInSearch() {
|
156 |
-
$
|
|
|
|
|
|
|
|
|
157 |
if (!$_isLNAllowedByEngine) {
|
158 |
return false;
|
159 |
}
|
160 |
$availableResCount = (int) Mage::app()->getStore()
|
161 |
->getConfig(Mage_CatalogSearch_Model_Layer::XML_PATH_DISPLAY_LAYER_COUNT);
|
162 |
|
163 |
-
if (
|
|
|
|
|
164 |
return false;
|
165 |
}
|
166 |
return $this->_canShowBlockInCategory();
|
167 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
29 |
{
|
30 |
/* @var $layoutHelper Mana_Core_Helper_Layout */
|
31 |
$layoutHelper = Mage::helper('mana_core/layout');
|
32 |
+
$layoutHelper->delayPrepareLayout($this, 200);
|
33 |
|
34 |
return $this;
|
35 |
}
|
52 |
|
53 |
$showState = 'all';
|
54 |
if ($showInFilter = $this->getShowInFilter()) {
|
55 |
+
if (($template = Mage::getStoreConfig('mana_filters/positioning/' . $showInFilter)) && !$this->getTakeTemplateFromXml()) {
|
56 |
$this->setTemplate($template);
|
57 |
}
|
58 |
$showState = Mage::getStoreConfig('mana_filters/positioning/show_state_' . $showInFilter);
|
81 |
'query' => $query,
|
82 |
'layer' => $layer,
|
83 |
'attribute_model' => $filterOptions->getAttribute(),
|
84 |
+
'mode' => $this->getMode(),
|
85 |
));
|
86 |
$block->init();
|
87 |
$this->setChild($filterOptions->getCode() . '_filter', $block);
|
94 |
return $this;
|
95 |
}
|
96 |
|
97 |
+
public function getMode() {
|
98 |
+
/* @var $helper Mana_Filters_Helper_Data */
|
99 |
+
$helper = Mage::helper(strtolower('Mana_Filters'));
|
100 |
+
|
101 |
+
if ($mode = $this->_getData('mode')) {
|
102 |
+
return $mode;
|
103 |
+
}
|
104 |
+
else {
|
105 |
+
return $helper->getMode();
|
106 |
+
}
|
107 |
+
}
|
108 |
public function getFilters() {
|
109 |
/* @var $helper Mana_Filters_Helper_Data */
|
110 |
$helper = Mage::helper(strtolower('Mana_Filters'));
|
136 |
/* @var $helper Mana_Filters_Helper_Data */
|
137 |
$helper = Mage::helper(strtolower('Mana_Filters'));
|
138 |
|
139 |
+
return $helper->getLayer($this->getMode());
|
140 |
}
|
141 |
|
142 |
public function canShowBlock() {
|
143 |
/* @var $helper Mana_Filters_Helper_Data */
|
144 |
$helper = Mage::helper(strtolower('Mana_Filters'));
|
145 |
|
146 |
+
switch ($this->getMode()) {
|
147 |
case 'category':
|
148 |
return $this->_canShowBlockInCategory();
|
149 |
case 'search':
|
164 |
}
|
165 |
}
|
166 |
public function _canShowBlockInSearch() {
|
167 |
+
$engine = Mage::helper('catalogsearch')->getEngine();
|
168 |
+
$_isLNAllowedByEngine = $engine->isLeyeredNavigationAllowed();
|
169 |
+
if (!$_isLNAllowedByEngine && method_exists($engine, 'isLayeredNavigationAllowed')) {
|
170 |
+
$_isLNAllowedByEngine = $engine->isLayeredNavigationAllowed();
|
171 |
+
}
|
172 |
if (!$_isLNAllowedByEngine) {
|
173 |
return false;
|
174 |
}
|
175 |
$availableResCount = (int) Mage::app()->getStore()
|
176 |
->getConfig(Mage_CatalogSearch_Model_Layer::XML_PATH_DISPLAY_LAYER_COUNT);
|
177 |
|
178 |
+
if (!$this->layerHelper()->useSolr() && $availableResCount &&
|
179 |
+
$availableResCount < $this->getLayer()->getProductCollection()->getSize())
|
180 |
+
{
|
181 |
return false;
|
182 |
}
|
183 |
return $this->_canShowBlockInCategory();
|
184 |
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* @return Mana_Filters_Helper_Data
|
188 |
+
*/
|
189 |
+
public function layerHelper() {
|
190 |
+
return Mage::helper('mana_filters');
|
191 |
+
}
|
192 |
}
|
app/code/local/Mana/Filters/Helper/Data.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
* Generic helper functions for Mana_Filters module. This class is a must for any module even if empty.
|
11 |
* @author Mana Team
|
12 |
*/
|
13 |
-
class Mana_Filters_Helper_Data extends
|
14 |
/**
|
15 |
* Return unique filter name.
|
16 |
* OO purists would say that kind of ifs should be done using virtual functions. Here we ignore OO-ness and
|
@@ -73,9 +73,9 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
73 |
}
|
74 |
else {
|
75 |
if (!$this->_filterOptionsCollection) {
|
76 |
-
Mana_Core_Profiler::start('mln'
|
77 |
$setIds = Mage::getSingleton('catalog/layer')->getProductCollection()->getSetIds();
|
78 |
-
Mana_Core_Profiler::stop('mln'
|
79 |
$this->_filterOptionsCollection = Mage::getResourceModel('mana_filters/filter2_store_collection')
|
80 |
->addFieldToSelect('*')
|
81 |
->addCodeFilter($this->_getAttributeCodes($setIds))
|
@@ -115,7 +115,7 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
115 |
}
|
116 |
return $url;
|
117 |
}
|
118 |
-
public function getClearUrl($markUrl = true, $clearListParams = false) {
|
119 |
$filterState = array();
|
120 |
foreach ($this->getLayer()->getState()->getFilters() as $item) {
|
121 |
$filterState[$item->getFilter()->getRequestVar()] = $item->getFilter()->getCleanValue();
|
@@ -135,8 +135,19 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
135 |
$params['_m_escape'] = '';
|
136 |
$filterState['m-layered'] = null;
|
137 |
$params['_query'] = $filterState;
|
|
|
|
|
|
|
138 |
$result = Mage::getUrl('*/*/*', $params);
|
139 |
-
if ($
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
$result = $this->markLayeredNavigationUrl($result, '*/*/*', $params);
|
141 |
}
|
142 |
return $result;
|
@@ -175,17 +186,6 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
175 |
}
|
176 |
$select->setPart(Zend_Db_Select::WHERE, $where);
|
177 |
}
|
178 |
-
/**
|
179 |
-
* @return Mage_Catalog_Model_Layer
|
180 |
-
*/
|
181 |
-
public function getMode() {
|
182 |
-
if (in_array(Mage::helper('mana_core')->getRoutePath(), array('catalogsearch/result/index', 'manapro_filterajax/search/index'))) {
|
183 |
-
return 'search';
|
184 |
-
}
|
185 |
-
else {
|
186 |
-
return 'category';
|
187 |
-
}
|
188 |
-
}
|
189 |
|
190 |
/**
|
191 |
* @param Mana_Filters_Model_Filter2_Store $filterOptions
|
@@ -202,26 +202,6 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
202 |
throw new Exception('Not implemented');
|
203 |
}
|
204 |
}
|
205 |
-
/**
|
206 |
-
* @return Mage_Catalog_Model_Layer
|
207 |
-
* @throws Exception
|
208 |
-
*/
|
209 |
-
public function getLayer () {
|
210 |
-
switch ($this->getMode()) {
|
211 |
-
case 'category':
|
212 |
-
return Mage::getSingleton($this->useSolrForNavigation()
|
213 |
-
? 'enterprise_search/catalog_layer'
|
214 |
-
: 'catalog/layer'
|
215 |
-
);
|
216 |
-
case 'search':
|
217 |
-
return Mage::getSingleton($this->useSolrForSearch()
|
218 |
-
? 'enterprise_search/search_layer'
|
219 |
-
: 'catalogsearch/layer'
|
220 |
-
);
|
221 |
-
default:
|
222 |
-
throw new Exception('Not implemented');
|
223 |
-
}
|
224 |
-
}
|
225 |
public function canShowFilterInBlock($block, $filter) {
|
226 |
if ($block->getData('show_'.$filter->getCode())) {
|
227 |
return true;
|
@@ -229,6 +209,12 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
229 |
elseif ($block->getData('hide_' . $filter->getCode())) {
|
230 |
return false;
|
231 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
elseif ($showInFilter = $block->getShowInFilter()) {
|
233 |
$showIn = $filter->getShowIn();
|
234 |
if (!is_array($showIn)) {
|
@@ -397,33 +383,31 @@ class Mana_Filters_Helper_Data extends Mage_Core_Helper_Abstract {
|
|
397 |
return $result;
|
398 |
}
|
399 |
|
400 |
-
public function
|
401 |
-
|
402 |
-
|
403 |
-
}
|
404 |
-
/* @var $helper Enterprise_Search_Helper_Data */
|
405 |
-
$helper = Mage::helper('enterprise_search');
|
406 |
|
407 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
}
|
409 |
-
public function useSolrForSearch() {
|
410 |
-
if (!Mage::helper('core')->isModuleEnabled('Enterprise_Search')) {
|
411 |
-
return false;
|
412 |
-
}
|
413 |
-
/* @var $helper Enterprise_Search_Helper_Data */
|
414 |
-
$helper = Mage::helper('enterprise_search');
|
415 |
|
416 |
-
|
417 |
-
}
|
418 |
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
return $this->useSolrForSearch();
|
425 |
-
default:
|
426 |
-
throw new Exception('Not implemented');
|
427 |
-
}
|
428 |
}
|
|
|
429 |
}
|
10 |
* Generic helper functions for Mana_Filters module. This class is a must for any module even if empty.
|
11 |
* @author Mana Team
|
12 |
*/
|
13 |
+
class Mana_Filters_Helper_Data extends Mana_Core_Helper_Layer {
|
14 |
/**
|
15 |
* Return unique filter name.
|
16 |
* OO purists would say that kind of ifs should be done using virtual functions. Here we ignore OO-ness and
|
73 |
}
|
74 |
else {
|
75 |
if (!$this->_filterOptionsCollection) {
|
76 |
+
Mana_Core_Profiler::start('mln' . '::' . __CLASS__ . '::' . __METHOD__ . '::' . '$productCollection->getSetIds()');
|
77 |
$setIds = Mage::getSingleton('catalog/layer')->getProductCollection()->getSetIds();
|
78 |
+
Mana_Core_Profiler::stop('mln' . '::' . __CLASS__ . '::' . __METHOD__ . '::' . '$productCollection->getSetIds()');
|
79 |
$this->_filterOptionsCollection = Mage::getResourceModel('mana_filters/filter2_store_collection')
|
80 |
->addFieldToSelect('*')
|
81 |
->addCodeFilter($this->_getAttributeCodes($setIds))
|
115 |
}
|
116 |
return $url;
|
117 |
}
|
118 |
+
public function getClearUrl($markUrl = true, $clearListParams = false, $nosid = false, $clearAllParams = false) {
|
119 |
$filterState = array();
|
120 |
foreach ($this->getLayer()->getState()->getFilters() as $item) {
|
121 |
$filterState[$item->getFilter()->getRequestVar()] = $item->getFilter()->getCleanValue();
|
135 |
$params['_m_escape'] = '';
|
136 |
$filterState['m-layered'] = null;
|
137 |
$params['_query'] = $filterState;
|
138 |
+
if ($nosid) {
|
139 |
+
$params['_nosid'] = true;
|
140 |
+
}
|
141 |
$result = Mage::getUrl('*/*/*', $params);
|
142 |
+
if ($clearAllParams) {
|
143 |
+
/* @var $mbstring Mana_Core_Helper_Mbstring */
|
144 |
+
$mbstring = Mage::helper('mana_core/mbstring');
|
145 |
+
|
146 |
+
if ($pos = $mbstring->strpos($result, '?')) {
|
147 |
+
$result = $mbstring->substr($result, 0, $pos);
|
148 |
+
}
|
149 |
+
}
|
150 |
+
elseif ($markUrl) {
|
151 |
$result = $this->markLayeredNavigationUrl($result, '*/*/*', $params);
|
152 |
}
|
153 |
return $result;
|
186 |
}
|
187 |
$select->setPart(Zend_Db_Select::WHERE, $where);
|
188 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
/**
|
191 |
* @param Mana_Filters_Model_Filter2_Store $filterOptions
|
202 |
throw new Exception('Not implemented');
|
203 |
}
|
204 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
public function canShowFilterInBlock($block, $filter) {
|
206 |
if ($block->getData('show_'.$filter->getCode())) {
|
207 |
return true;
|
209 |
elseif ($block->getData('hide_' . $filter->getCode())) {
|
210 |
return false;
|
211 |
}
|
212 |
+
elseif ($block->getData('show_all_filters')) {
|
213 |
+
return true;
|
214 |
+
}
|
215 |
+
elseif ($block->getData('hide_all_filters')) {
|
216 |
+
return false;
|
217 |
+
}
|
218 |
elseif ($showInFilter = $block->getShowInFilter()) {
|
219 |
$showIn = $filter->getShowIn();
|
220 |
if (!is_array($showIn)) {
|
383 |
return $result;
|
384 |
}
|
385 |
|
386 |
+
public function isTreeVisible() {
|
387 |
+
/* @var $core Mana_Core_Helper_Data */
|
388 |
+
$core = Mage::helper('mana_core');
|
|
|
|
|
|
|
389 |
|
390 |
+
if ($core->isManadevLayeredNavigationTreeInstalled()) {
|
391 |
+
$filterCollection = $this->getFilterOptionsCollection(true);
|
392 |
+
foreach ($filterCollection as $filter) {
|
393 |
+
/* @var $filter Mana_Filters_Model_Filter2_Store */
|
394 |
+
if ($filter->getType() == 'category') {
|
395 |
+
if ($filter->getData('display') == 'tree') {
|
396 |
+
return true;
|
397 |
+
}
|
398 |
+
}
|
399 |
+
}
|
400 |
+
}
|
401 |
+
return false;
|
402 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
403 |
|
404 |
+
#region Dependencies
|
|
|
405 |
|
406 |
+
/**
|
407 |
+
* @return Mana_Core_Helper_Data
|
408 |
+
*/
|
409 |
+
public function coreHelper() {
|
410 |
+
return Mage::helper('mana_core');
|
|
|
|
|
|
|
|
|
411 |
}
|
412 |
+
#endregion
|
413 |
}
|
app/code/local/Mana/Filters/Model/Filter/Attribute.php
CHANGED
@@ -9,6 +9,8 @@
|
|
9 |
* Model type for holding information in memory about possible or applied filter which is based on an attribute
|
10 |
* @author Mana Team
|
11 |
* Injected instead of standard catalog/layer_filter_attribute in Mana_Filters_Block_Filter_Attribute constructor.
|
|
|
|
|
12 |
*/
|
13 |
class Mana_Filters_Model_Filter_Attribute
|
14 |
extends Mage_Catalog_Model_Layer_Filter_Attribute
|
@@ -104,12 +106,13 @@ class Mana_Filters_Model_Filter_Attribute
|
|
104 |
);
|
105 |
|
106 |
$tags = $this->getLayer()->getStateTags($tags);
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
usort($data, array(Mage::getSingleton('mana_filters/sort'), $sortMethod));
|
112 |
}
|
|
|
|
|
113 |
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
|
114 |
}
|
115 |
|
9 |
* Model type for holding information in memory about possible or applied filter which is based on an attribute
|
10 |
* @author Mana Team
|
11 |
* Injected instead of standard catalog/layer_filter_attribute in Mana_Filters_Block_Filter_Attribute constructor.
|
12 |
+
*
|
13 |
+
* @method Mana_Filters_Model_Filter2_Store getFilterOptions()
|
14 |
*/
|
15 |
class Mana_Filters_Model_Filter_Attribute
|
16 |
extends Mage_Catalog_Model_Layer_Filter_Attribute
|
106 |
);
|
107 |
|
108 |
$tags = $this->getLayer()->getStateTags($tags);
|
109 |
+
|
110 |
+
$sortMethod = $this->getFilterOptions()->getSortMethod() ? $this->getFilterOptions()->getSortMethod() : 'byPosition';
|
111 |
+
foreach ($data as $position => &$item) {
|
112 |
+
$item['position'] = $position;
|
|
|
113 |
}
|
114 |
+
usort($data, array(Mage::getSingleton('mana_filters/sort'), $sortMethod));
|
115 |
+
|
116 |
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
|
117 |
}
|
118 |
|
app/code/local/Mana/Filters/Model/Filter/Category.php
CHANGED
@@ -9,6 +9,7 @@
|
|
9 |
* Model type for holding information in memory about possible or applied category filter
|
10 |
* @author Mana Team
|
11 |
* Injected instead of standard catalog/layer_filter_attribute in Mana_Filters_Block_Filter_Category constructor.
|
|
|
12 |
*/
|
13 |
class Mana_Filters_Model_Filter_Category
|
14 |
extends Mage_Catalog_Model_Layer_Filter_Category
|
@@ -58,7 +59,8 @@ class Mana_Filters_Model_Filter_Category
|
|
58 |
{
|
59 |
$data = array();
|
60 |
foreach ($categories as $category) {
|
61 |
-
if ($category->getIsActive() &&
|
|
|
62 |
$data[] = array(
|
63 |
'label' => Mage::helper('core')->htmlEscape($category->getName()),
|
64 |
'value' => $category->getId(),
|
@@ -314,4 +316,29 @@ class Mana_Filters_Model_Filter_Category
|
|
314 |
}
|
315 |
#endregion
|
316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
}
|
9 |
* Model type for holding information in memory about possible or applied category filter
|
10 |
* @author Mana Team
|
11 |
* Injected instead of standard catalog/layer_filter_attribute in Mana_Filters_Block_Filter_Category constructor.
|
12 |
+
* @method Mana_Filters_Model_Filter2_Store getFilterOptions()
|
13 |
*/
|
14 |
class Mana_Filters_Model_Filter_Category
|
15 |
extends Mage_Catalog_Model_Layer_Filter_Category
|
59 |
{
|
60 |
$data = array();
|
61 |
foreach ($categories as $category) {
|
62 |
+
if ($category->getIsActive() &&
|
63 |
+
($this->filterHelper()->isFilterEnabled($this->getFilterOptions()) == 2 || $category->getProductCount())) {
|
64 |
$data[] = array(
|
65 |
'label' => Mage::helper('core')->htmlEscape($category->getName()),
|
66 |
'value' => $category->getId(),
|
316 |
}
|
317 |
#endregion
|
318 |
|
319 |
+
public function getResetValue() {
|
320 |
+
if ($this->_appliedCategory) {
|
321 |
+
/**
|
322 |
+
* Revert path ids
|
323 |
+
*/
|
324 |
+
$pathIds = array_reverse($this->_appliedCategory->getPathIds());
|
325 |
+
$curCategoryId = $this->getLayer()->getCurrentCategory()->getId();
|
326 |
+
|
327 |
+
if ($pathIds[0] != $curCategoryId && in_array($curCategoryId, $pathIds) && isset($pathIds[1]) && $pathIds[1] != $curCategoryId) {
|
328 |
+
return $pathIds[1];
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
return null;
|
333 |
+
}
|
334 |
+
|
335 |
+
#region Dependencies
|
336 |
+
|
337 |
+
/**
|
338 |
+
* @return Mana_Filters_Helper_Data
|
339 |
+
*/
|
340 |
+
public function filterHelper() {
|
341 |
+
return Mage::helper('mana_filters');
|
342 |
+
}
|
343 |
+
#endregion
|
344 |
}
|
app/code/local/Mana/Filters/Model/Filter/Decimal.php
CHANGED
@@ -30,8 +30,8 @@ class Mana_Filters_Model_Filter_Decimal
|
|
30 |
return $result->getLabel();
|
31 |
} else {
|
32 |
$store = Mage::app()->getStore();
|
33 |
-
$fromPrice = $store->formatPrice($range['from']);
|
34 |
-
$toPrice = $store->formatPrice($range['to']);
|
35 |
|
36 |
return Mage::helper('catalog')->__('%s - %s', $fromPrice, $toPrice);
|
37 |
}
|
@@ -55,8 +55,10 @@ class Mana_Filters_Model_Filter_Decimal
|
|
55 |
if ($this->_getIsFilterable() == 2) {
|
56 |
$nonEmptyRanges = $dbRanges;
|
57 |
$dbRanges = array();
|
58 |
-
|
59 |
-
|
|
|
|
|
60 |
}
|
61 |
}
|
62 |
$data = array();
|
@@ -305,7 +307,7 @@ class Mana_Filters_Model_Filter_Decimal
|
|
305 |
$range = $this->getData('range');
|
306 |
|
307 |
$value = $this->getMSelectedValues();
|
308 |
-
if (!empty($value)) {
|
309 |
list($index, $range) = explode(',', $value[0]);
|
310 |
}
|
311 |
|
@@ -392,9 +394,11 @@ class Mana_Filters_Model_Filter_Decimal
|
|
392 |
* Returns all values currently selected for this filter
|
393 |
*/
|
394 |
public function getMSelectedValues() {
|
395 |
-
$values = Mage::helper('mana_core')->sanitizeRequestNumberParam($this->_requestVar,
|
396 |
-
|
397 |
-
|
|
|
|
|
398 |
}
|
399 |
|
400 |
/**
|
@@ -416,17 +420,19 @@ class Mana_Filters_Model_Filter_Decimal
|
|
416 |
public function addToState()
|
417 |
{
|
418 |
foreach ($this->getMSelectedValues() as $selection) {
|
419 |
-
|
420 |
-
|
421 |
-
$this->
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
|
|
|
|
427 |
)
|
428 |
-
)
|
429 |
-
|
430 |
}
|
431 |
}
|
432 |
|
30 |
return $result->getLabel();
|
31 |
} else {
|
32 |
$store = Mage::app()->getStore();
|
33 |
+
$fromPrice = $store->formatPrice($range['from'], false);
|
34 |
+
$toPrice = $store->formatPrice($range['to'], false);
|
35 |
|
36 |
return Mage::helper('catalog')->__('%s - %s', $fromPrice, $toPrice);
|
37 |
}
|
55 |
if ($this->_getIsFilterable() == 2) {
|
56 |
$nonEmptyRanges = $dbRanges;
|
57 |
$dbRanges = array();
|
58 |
+
$from = (int)floor($this->getMinValue() / $range);
|
59 |
+
$to = (int)floor($this->getMaxValue() / $range);
|
60 |
+
for ($i = $from; $i <= $to; $i++) {
|
61 |
+
$dbRanges[$i] = isset($nonEmptyRanges[$i]) ? $nonEmptyRanges[$i] : 0;
|
62 |
}
|
63 |
}
|
64 |
$data = array();
|
307 |
$range = $this->getData('range');
|
308 |
|
309 |
$value = $this->getMSelectedValues();
|
310 |
+
if (!empty($value) && strpos($value[0], ',') !== false) {
|
311 |
list($index, $range) = explode(',', $value[0]);
|
312 |
}
|
313 |
|
394 |
* Returns all values currently selected for this filter
|
395 |
*/
|
396 |
public function getMSelectedValues() {
|
397 |
+
$values = Mage::helper('mana_core')->sanitizeRequestNumberParam($this->_requestVar, array(
|
398 |
+
array('sep' => '_', 'as_string' => true),
|
399 |
+
array('sep' => ',', 'as_string' => true)
|
400 |
+
));
|
401 |
+
return $values ? explode('_', $values) : array();
|
402 |
}
|
403 |
|
404 |
/**
|
420 |
public function addToState()
|
421 |
{
|
422 |
foreach ($this->getMSelectedValues() as $selection) {
|
423 |
+
if (strpos($selection, ',') !== false) {
|
424 |
+
list($index, $range) = explode(',', $selection);
|
425 |
+
$this->getLayer()->getState()->addFilter(
|
426 |
+
$this->_createItemEx(
|
427 |
+
array(
|
428 |
+
'label' => $this->_renderItemLabel($range, $index),
|
429 |
+
'value' => $selection,
|
430 |
+
'm_selected' => true,
|
431 |
+
'm_show_selected' => $this->getFilterOptions()->getIsReverse(),
|
432 |
+
)
|
433 |
)
|
434 |
+
);
|
435 |
+
}
|
436 |
}
|
437 |
}
|
438 |
|
app/code/local/Mana/Filters/Model/Filter/Price.php
CHANGED
@@ -110,10 +110,16 @@ class Mana_Filters_Model_Filter_Price
|
|
110 |
->setStoreId(Mage::app()->getStore()->getId())
|
111 |
->load(Mage::app()->getStore()->getRootCategoryId());
|
112 |
$currentCategory = $this->getLayer()->getCurrentCategory();
|
113 |
-
$
|
114 |
-
|
115 |
-
$this->
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
$this->_maxPriceInt = $queryResult['max'];
|
118 |
$this->_hasNoResults = true;
|
119 |
}
|
@@ -310,66 +316,70 @@ class Mana_Filters_Model_Filter_Price
|
|
310 |
}
|
311 |
|
312 |
public function getPriceRange() {
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
if (!empty($value)) {
|
317 |
-
list($index, $range) = explode(',', $value[0]);
|
318 |
-
}
|
319 |
|
320 |
-
|
321 |
-
if (
|
322 |
-
$range = (
|
323 |
-
}
|
324 |
-
elseif (Mage::helper('mana_db')->hasOverriddenValueEx($this->getFilterOptions(), 24, 'global_default_mask')) {
|
325 |
-
$range = (float)$this->getFilterOptions()->getGlobalRangeStep();
|
326 |
-
}
|
327 |
-
}
|
328 |
-
if (!$range) {
|
329 |
-
$currentCategory = Mage::registry('current_category_filter');
|
330 |
-
if ($currentCategory) {
|
331 |
-
$range = $currentCategory->getFilterPriceRange();
|
332 |
-
} else {
|
333 |
-
$range = $this->getLayer()->getCurrentCategory()->getFilterPriceRange();
|
334 |
}
|
335 |
|
336 |
-
$maxPrice = $this->getMaxPriceInt();
|
337 |
if (!$range) {
|
338 |
-
|
339 |
-
|
340 |
-
$calculation = 'auto';
|
341 |
}
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
}
|
349 |
-
|
350 |
-
$
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
$query = $this->getQuery();
|
356 |
-
$items = $query->getFilterCounts($this->getFilterOptions()->getCode(), false);
|
357 |
-
$index++;
|
358 |
}
|
359 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
|
362 |
-
|
363 |
-
|
|
|
364 |
}
|
365 |
}
|
366 |
-
|
367 |
-
|
|
|
368 |
}
|
369 |
-
}
|
370 |
|
|
|
|
|
371 |
}
|
372 |
-
$this->setData('price_range', $range);
|
373 |
return $this->getData('price_range');
|
374 |
}
|
375 |
public function init() {
|
@@ -378,9 +388,11 @@ class Mana_Filters_Model_Filter_Price
|
|
378 |
* Returns all values currently selected for this filter
|
379 |
*/
|
380 |
public function getMSelectedValues() {
|
381 |
-
$values = Mage::helper('mana_core')->sanitizeRequestNumberParam($this->_requestVar,
|
382 |
-
|
383 |
-
|
|
|
|
|
384 |
}
|
385 |
|
386 |
/**
|
@@ -391,17 +403,19 @@ class Mana_Filters_Model_Filter_Price
|
|
391 |
public function addToState()
|
392 |
{
|
393 |
foreach ($this->getMSelectedValues() as $selection) {
|
394 |
-
|
395 |
-
|
396 |
-
$this->
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
|
|
|
|
402 |
)
|
403 |
-
)
|
404 |
-
|
405 |
}
|
406 |
}
|
407 |
|
110 |
->setStoreId(Mage::app()->getStore()->getId())
|
111 |
->load(Mage::app()->getStore()->getRootCategoryId());
|
112 |
$currentCategory = $this->getLayer()->getCurrentCategory();
|
113 |
+
if ($rootCategory->getId() != $currentCategory->getId()) {
|
114 |
+
$this->getLayer()->setCurrentCategory($rootCategory);
|
115 |
+
$queryResult = $query->getFilterRange($this->getFilterOptions()->getCode(), false,
|
116 |
+
$this->getLayer()->getProductCollection(), false);
|
117 |
+
$this->getLayer()->setCurrentCategory($currentCategory);
|
118 |
+
}
|
119 |
+
else {
|
120 |
+
$queryResult = $query->getFilterRange($this->getFilterOptions()->getCode(), false,
|
121 |
+
$query->createProductCollection(), false);
|
122 |
+
}
|
123 |
$this->_maxPriceInt = $queryResult['max'];
|
124 |
$this->_hasNoResults = true;
|
125 |
}
|
316 |
}
|
317 |
|
318 |
public function getPriceRange() {
|
319 |
+
if (!$this->getData('price_range_set')) {
|
320 |
+
$this->setData('price_range_set', true);
|
321 |
+
$range = $this->getData('price_range');
|
|
|
|
|
|
|
322 |
|
323 |
+
$value = $this->getMSelectedValues();
|
324 |
+
if (!empty($value) && strpos($value[0], ',') !== false) {
|
325 |
+
list($index, $range) = explode(',', $value[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
}
|
327 |
|
|
|
328 |
if (!$range) {
|
329 |
+
if (Mage::helper('mana_db')->hasOverriddenValueEx($this->getFilterOptions(), 24)) {
|
330 |
+
$range = (float)$this->getFilterOptions()->getRangeStep();
|
|
|
331 |
}
|
332 |
+
elseif (Mage::helper('mana_db')->hasOverriddenValueEx($this->getFilterOptions(), 24, 'global_default_mask')) {
|
333 |
+
$range = (float)$this->getFilterOptions()->getGlobalRangeStep();
|
334 |
+
}
|
335 |
+
}
|
336 |
+
if (!$range) {
|
337 |
+
$currentCategory = Mage::registry('current_category_filter');
|
338 |
+
if ($currentCategory) {
|
339 |
+
$range = $currentCategory->getFilterPriceRange();
|
340 |
+
}
|
341 |
+
else {
|
342 |
+
$range = $this->getLayer()->getCurrentCategory()->getFilterPriceRange();
|
343 |
+
}
|
344 |
+
|
345 |
+
$maxPrice = $this->getMaxPriceInt();
|
346 |
+
if (!$range) {
|
347 |
+
$calculation = Mage::app()->getStore()->getConfig('catalog/layered_navigation/price_range_calculation');
|
348 |
+
if (!$calculation) {
|
349 |
+
$calculation = 'auto';
|
350 |
}
|
351 |
+
if ($calculation == 'auto') {
|
352 |
+
if ($this->hasNoResults()) {
|
353 |
+
$range = 1;
|
354 |
+
while (ceil($maxPrice / $range) > 10) {
|
355 |
+
$range *= 10;
|
356 |
+
}
|
|
|
|
|
|
|
357 |
}
|
358 |
+
else {
|
359 |
+
$index = 1;
|
360 |
+
do {
|
361 |
+
$range = pow(10, (strlen(floor($maxPrice)) - $index));
|
362 |
+
$this->setData('price_range', $range);
|
363 |
+
/* @var $query Mana_Filters_Model_Query */
|
364 |
+
$query = $this->getQuery();
|
365 |
+
$items = $query->getFilterCounts($this->getFilterOptions()->getCode(), false);
|
366 |
+
$index++;
|
367 |
+
} while ($range > self::MIN_RANGE_POWER && count($items) < 2);
|
368 |
|
369 |
|
370 |
+
while (ceil($maxPrice / $range) > 25) {
|
371 |
+
$range *= 10;
|
372 |
+
}
|
373 |
}
|
374 |
}
|
375 |
+
else {
|
376 |
+
$range = Mage::app()->getStore()->getConfig('catalog/layered_navigation/price_range_step');
|
377 |
+
}
|
378 |
}
|
|
|
379 |
|
380 |
+
}
|
381 |
+
$this->setData('price_range', $range);
|
382 |
}
|
|
|
383 |
return $this->getData('price_range');
|
384 |
}
|
385 |
public function init() {
|
388 |
* Returns all values currently selected for this filter
|
389 |
*/
|
390 |
public function getMSelectedValues() {
|
391 |
+
$values = Mage::helper('mana_core')->sanitizeRequestNumberParam($this->_requestVar, array(
|
392 |
+
array('sep' => '_', 'as_string' => true),
|
393 |
+
array('sep' => ',', 'as_string' => true)
|
394 |
+
));
|
395 |
+
return $values ? explode('_', $values) : array();
|
396 |
}
|
397 |
|
398 |
/**
|
403 |
public function addToState()
|
404 |
{
|
405 |
foreach ($this->getMSelectedValues() as $selection) {
|
406 |
+
if (strpos($selection, ',') !== false) {
|
407 |
+
list($index, $range) = explode(',', $selection);
|
408 |
+
$this->getLayer()->getState()->addFilter(
|
409 |
+
$this->_createItemEx(
|
410 |
+
array(
|
411 |
+
'label' => $this->_renderItemLabel($range, $index),
|
412 |
+
'value' => $selection,
|
413 |
+
'm_selected' => true,
|
414 |
+
'm_show_selected' => $this->getFilterOptions()->getIsReverse(),
|
415 |
+
)
|
416 |
)
|
417 |
+
);
|
418 |
+
}
|
419 |
}
|
420 |
}
|
421 |
|
app/code/local/Mana/Filters/Model/Filter2.php
CHANGED
@@ -10,9 +10,11 @@
|
|
10 |
/**
|
11 |
* INSERT HERE: what is this model for
|
12 |
* @author Mana Team
|
|
|
13 |
*/
|
14 |
class Mana_Filters_Model_Filter2 extends Mana_Db_Model_Object {
|
15 |
protected $_eventPrefix = 'mana_filter';
|
|
|
16 |
|
17 |
/**
|
18 |
* Invoked during model creation process, this method associates this model with resource and resource
|
@@ -58,4 +60,27 @@ class Mana_Filters_Model_Filter2 extends Mana_Db_Model_Object {
|
|
58 |
public function getCode() {
|
59 |
return isset($this->_data['code']) ? $this->_data['code'] : null;
|
60 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
10 |
/**
|
11 |
* INSERT HERE: what is this model for
|
12 |
* @author Mana Team
|
13 |
+
* @method string getType()
|
14 |
*/
|
15 |
class Mana_Filters_Model_Filter2 extends Mana_Db_Model_Object {
|
16 |
protected $_eventPrefix = 'mana_filter';
|
17 |
+
protected $_entity = 'mana_filters/filter2';
|
18 |
|
19 |
/**
|
20 |
* Invoked during model creation process, this method associates this model with resource and resource
|
60 |
public function getCode() {
|
61 |
return isset($this->_data['code']) ? $this->_data['code'] : null;
|
62 |
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Init indexing process after category data commit
|
66 |
+
*
|
67 |
+
* @return Mage_Catalog_Model_Category
|
68 |
+
*/
|
69 |
+
public function afterCommitCallback() {
|
70 |
+
parent::afterCommitCallback();
|
71 |
+
if (!Mage::registry('m_prevent_indexing_on_save')) {
|
72 |
+
$this->getIndexerSingleton()->processEntityAction($this, $this->_entity, Mage_Index_Model_Event::TYPE_SAVE);
|
73 |
+
}
|
74 |
+
|
75 |
+
return $this;
|
76 |
+
}
|
77 |
+
|
78 |
+
#region Dependencies
|
79 |
+
/**
|
80 |
+
* @return Mage_Index_Model_Indexer
|
81 |
+
*/
|
82 |
+
public function getIndexerSingleton() {
|
83 |
+
return Mage::getSingleton('index/indexer');
|
84 |
+
}
|
85 |
+
#endregion
|
86 |
}
|
app/code/local/Mana/Filters/Model/Filter2/Store.php
CHANGED
@@ -13,6 +13,8 @@
|
|
13 |
*/
|
14 |
class Mana_Filters_Model_Filter2_Store extends Mana_Filters_Model_Filter2 {
|
15 |
protected $_eventPrefix = 'mana_filter_store';
|
|
|
|
|
16 |
/**
|
17 |
* Invoked during model creation process, this method associates this model with resource and resource
|
18 |
* collection classes
|
@@ -30,7 +32,8 @@ class Mana_Filters_Model_Filter2_Store extends Mana_Filters_Model_Filter2 {
|
|
30 |
$result = $this->getData($field);
|
31 |
$store = Mage::app()->getStore();
|
32 |
if ($result == '$0') {
|
33 |
-
return
|
|
|
34 |
}
|
35 |
else {
|
36 |
return $result;
|
13 |
*/
|
14 |
class Mana_Filters_Model_Filter2_Store extends Mana_Filters_Model_Filter2 {
|
15 |
protected $_eventPrefix = 'mana_filter_store';
|
16 |
+
protected $_entity = 'mana_filters/filter2_store';
|
17 |
+
|
18 |
/**
|
19 |
* Invoked during model creation process, this method associates this model with resource and resource
|
20 |
* collection classes
|
32 |
$result = $this->getData($field);
|
33 |
$store = Mage::app()->getStore();
|
34 |
if ($result == '$0') {
|
35 |
+
return str_replace('.00', '', str_replace(',00', '',
|
36 |
+
$store->getCurrentCurrency()->formatPrecision(0, 0, array(), false, false)));
|
37 |
}
|
38 |
else {
|
39 |
return $result;
|
app/code/local/Mana/Filters/Model/Filter2/Value.php
CHANGED
@@ -20,4 +20,15 @@ class Mana_Filters_Model_Filter2_Value extends Mana_Db_Model_Object {
|
|
20 |
protected function _construct() {
|
21 |
$this->_init(strtolower('Mana_Filters/Filter2_Value'));
|
22 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
20 |
protected function _construct() {
|
21 |
$this->_init(strtolower('Mana_Filters/Filter2_Value'));
|
22 |
}
|
23 |
+
|
24 |
+
public function loadByFilterPosition($filterId, $position) {
|
25 |
+
/* @var $resource Mana_Filters_Resource_Filter2_Value */
|
26 |
+
$resource = $this->_getResource();
|
27 |
+
$resource->loadByFilterPosition($this, $filterId, $position);
|
28 |
+
$this->_afterLoad();
|
29 |
+
$this->setOrigData();
|
30 |
+
$this->_hasDataChanges = false;
|
31 |
+
|
32 |
+
return $this;
|
33 |
+
}
|
34 |
}
|
app/code/local/Mana/Filters/Model/Item.php
CHANGED
@@ -14,6 +14,8 @@
|
|
14 |
* method.
|
15 |
*/
|
16 |
class Mana_Filters_Model_Item extends Mage_Catalog_Model_Layer_Filter_Item {
|
|
|
|
|
17 |
/**
|
18 |
* Returns URL which should be loaded if person chooses to add this filter item into active filters
|
19 |
* @return string
|
@@ -101,14 +103,42 @@ class Mana_Filters_Model_Item extends Mage_Catalog_Model_Layer_Filter_Item {
|
|
101 |
return 'filter_'.$helper->getFilterName($block, $this->getFilter()).'_'.$this->getValue();
|
102 |
}
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
}
|
112 |
-
|
|
|
113 |
}
|
114 |
}
|
14 |
* method.
|
15 |
*/
|
16 |
class Mana_Filters_Model_Item extends Mage_Catalog_Model_Layer_Filter_Item {
|
17 |
+
protected $_seoData;
|
18 |
+
|
19 |
/**
|
20 |
* Returns URL which should be loaded if person chooses to add this filter item into active filters
|
21 |
* @return string
|
103 |
return 'filter_'.$helper->getFilterName($block, $this->getFilter()).'_'.$this->getValue();
|
104 |
}
|
105 |
|
106 |
+
/**
|
107 |
+
* @return string
|
108 |
+
*/
|
109 |
+
public function getSeoValue() {
|
110 |
+
return $this->getSeoData('url');
|
111 |
+
}
|
112 |
+
|
113 |
+
public function getSeoPrefix()
|
114 |
+
{
|
115 |
+
return $this->getSeoData('prefix');
|
116 |
+
}
|
117 |
+
|
118 |
+
public function getSeoPosition()
|
119 |
+
{
|
120 |
+
return $this->getSeoData('position');
|
121 |
+
}
|
122 |
+
|
123 |
+
public function getSeoData($key = false) {
|
124 |
+
if (!$this->_seoData) {
|
125 |
+
if (Mage::app()->getRequest()->getParam('m-seo-enabled', true) &&
|
126 |
+
((string)Mage::getConfig()->getNode('modules/ManaPro_FilterSeoLinks/active')) == 'true'
|
127 |
+
) {
|
128 |
+
/* @var $url Mana_Seo_Rewrite_Url */
|
129 |
+
$url = Mage::getModel('core/url');
|
130 |
+
$this->_seoData = $url->getItemData($this->getFilter()->getRequestVar(), $this->getValue());
|
131 |
+
}
|
132 |
+
else {
|
133 |
+
$this->_seoData = array(
|
134 |
+
'url' => $this->getValue(),
|
135 |
+
'prefix' => '',
|
136 |
+
'position' => 0,
|
137 |
+
'id' => 0,
|
138 |
+
);
|
139 |
+
}
|
140 |
}
|
141 |
+
|
142 |
+
return $key !== false ? $this->_seoData[$key] : $this->_seoData;
|
143 |
}
|
144 |
}
|
app/code/local/Mana/Filters/Model/Observer.php
CHANGED
@@ -29,6 +29,7 @@ class Mana_Filters_Model_Observer {
|
|
29 |
'mana_filters/display/category',
|
30 |
'mana_filters/display/decimal',
|
31 |
'mana_filters/display/sort_method',
|
|
|
32 |
));
|
33 |
}
|
34 |
/**
|
@@ -50,7 +51,11 @@ class Mana_Filters_Model_Observer {
|
|
50 |
* @param Varien_Event_Observer $observer
|
51 |
*/
|
52 |
public function fixAttributeIndexerSelectForConfigurableProductDefaultValues($observer) {
|
53 |
-
|
|
|
|
|
|
|
|
|
54 |
/* @var $entityField Zend_Db_Expr */ $entityField = $observer->getEvent()->getEntityField();
|
55 |
|
56 |
/* @var $res Mage_Core_Model_Resource */ $res = Mage::getSingleton('core/resource');
|
@@ -69,4 +74,43 @@ class Mana_Filters_Model_Observer {
|
|
69 |
->where("NOT((m_configurable_product.type_id = 'configurable') AND (m_configurable_attribute.is_configurable = 1))");
|
70 |
}
|
71 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
29 |
'mana_filters/display/category',
|
30 |
'mana_filters/display/decimal',
|
31 |
'mana_filters/display/sort_method',
|
32 |
+
'mana_filters/display/disable_no_result_options',
|
33 |
));
|
34 |
}
|
35 |
/**
|
51 |
* @param Varien_Event_Observer $observer
|
52 |
*/
|
53 |
public function fixAttributeIndexerSelectForConfigurableProductDefaultValues($observer) {
|
54 |
+
if (Mage::helper('mana_core')->isMageVersionEqualOrGreater('1.7')) {
|
55 |
+
return;
|
56 |
+
}
|
57 |
+
|
58 |
+
/* @var $select Varien_Db_Select */ $select = $observer->getEvent()->getSelect();
|
59 |
/* @var $entityField Zend_Db_Expr */ $entityField = $observer->getEvent()->getEntityField();
|
60 |
|
61 |
/* @var $res Mage_Core_Model_Resource */ $res = Mage::getSingleton('core/resource');
|
74 |
->where("NOT((m_configurable_product.type_id = 'configurable') AND (m_configurable_attribute.is_configurable = 1))");
|
75 |
}
|
76 |
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* REPLACE THIS WITH DESCRIPTION (handles event "core_block_abstract_to_html_after")
|
80 |
+
* @param Varien_Event_Observer $observer
|
81 |
+
*/
|
82 |
+
public function hideCmsContentOnFilteredPages($observer) {
|
83 |
+
/* @var $block Mage_Core_Block_Abstract */
|
84 |
+
$block = $observer->getEvent()->getBlock();
|
85 |
+
/* @var $transport Varien_Object */
|
86 |
+
$transport = $observer->getEvent()->getData('transport');
|
87 |
+
|
88 |
+
if ($block->getNameInLayout() == 'cms_page' &&
|
89 |
+
($block->getData('hide_cms_content_when_filters_applied') || Mage::getStoreConfigFlag('mana_filters/display/hide_cms_page_content')) &&
|
90 |
+
in_array($this->coreHelper()->getRoutePath(), array('cms/page/view', 'cms/index/index')) &&
|
91 |
+
($state = $this->filterHelper()->getLayer()->getState()) &&
|
92 |
+
$state->getFilters())
|
93 |
+
|
94 |
+
{
|
95 |
+
$transport->setData('html', '');
|
96 |
+
}
|
97 |
+
// INSERT HERE: event handler code
|
98 |
+
}
|
99 |
+
|
100 |
+
#region Dependencies
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @return Mana_Core_Helper_Data
|
104 |
+
*/
|
105 |
+
public function coreHelper() {
|
106 |
+
return Mage::helper('mana_core');
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @return Mana_Filters_Helper_Data
|
111 |
+
*/
|
112 |
+
public function filterHelper() {
|
113 |
+
return Mage::helper('mana_filters');
|
114 |
+
}
|
115 |
+
#endregion
|
116 |
}
|
app/code/local/Mana/Filters/Model/Query.php
CHANGED
@@ -160,6 +160,7 @@ class Mana_Filters_Model_Query extends Varien_Object
|
|
160 |
$filterModel->applyToCollection($collection);
|
161 |
}
|
162 |
}
|
|
|
163 |
$counts = $currentFilterModel->countOnCollection($collection);
|
164 |
$currentFilter['processedCounts'] = $currentFilterModel->processCounts($counts);
|
165 |
|
160 |
$filterModel->applyToCollection($collection);
|
161 |
}
|
162 |
}
|
163 |
+
|
164 |
$counts = $currentFilterModel->countOnCollection($collection);
|
165 |
$currentFilter['processedCounts'] = $currentFilterModel->processCounts($counts);
|
166 |
|
app/code/local/Mana/Filters/Model/Solr/Attribute.php
CHANGED
@@ -19,11 +19,40 @@ class Mana_Filters_Model_Solr_Attribute extends Mana_Filters_Model_Filter_Attrib
|
|
19 |
/* @var $collection Enterprise_Search_Model_Resource_Collection */
|
20 |
$collection = $counts;
|
21 |
|
22 |
-
$
|
23 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
/**
|
@@ -32,9 +61,7 @@ class Mana_Filters_Model_Solr_Attribute extends Mana_Filters_Model_Filter_Attrib
|
|
32 |
*/
|
33 |
public function countOnCollection($collection)
|
34 |
{
|
35 |
-
$
|
36 |
-
$facetField = $engine->getSearchEngineFieldName($this->getAttributeModel(), 'nav');
|
37 |
-
$collection->setFacetCondition($facetField);
|
38 |
|
39 |
return $collection;
|
40 |
}
|
@@ -44,9 +71,16 @@ class Mana_Filters_Model_Solr_Attribute extends Mana_Filters_Model_Filter_Attrib
|
|
44 |
*/
|
45 |
public function applyToCollection($collection)
|
46 |
{
|
|
|
47 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
}
|
19 |
/* @var $collection Enterprise_Search_Model_Resource_Collection */
|
20 |
$collection = $counts;
|
21 |
|
22 |
+
$result = $collection->getFacetedData($this->getFilterField(), array('fields' => array('id')));
|
23 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
24 |
+
if (method_exists($engine, 'getSearchEngineFieldName')) {
|
25 |
+
return $result;
|
26 |
+
}
|
27 |
+
else {
|
28 |
+
$attribute = $this->getAttributeModel();
|
29 |
+
$options = $attribute->getFrontend()->getSelectOptions();
|
30 |
+
$idResult = array();
|
31 |
+
foreach ($options as $option) {
|
32 |
+
if (!$option || is_array($option['value'])) {
|
33 |
+
continue;
|
34 |
+
}
|
35 |
+
if (isset($result[$option['label']])) {
|
36 |
+
$idResult[$option['value']] = $result[$option['label']];
|
37 |
+
}
|
38 |
+
}
|
39 |
+
return $idResult;
|
40 |
+
}
|
41 |
+
}
|
42 |
|
43 |
+
/**
|
44 |
+
* Get facet field name
|
45 |
+
*
|
46 |
+
* @return string
|
47 |
+
*/
|
48 |
+
public function getFilterField() {
|
49 |
+
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
50 |
+
if (method_exists($engine, 'getSearchEngineFieldName')) {
|
51 |
+
return $engine->getSearchEngineFieldName($this->getAttributeModel(), 'nav');
|
52 |
+
}
|
53 |
+
else {
|
54 |
+
return Mage::helper('enterprise_search')->getAttributeSolrFieldName($this->getAttributeModel());
|
55 |
+
}
|
56 |
}
|
57 |
|
58 |
/**
|
61 |
*/
|
62 |
public function countOnCollection($collection)
|
63 |
{
|
64 |
+
$collection->setFacetCondition($this->getFilterField());
|
|
|
|
|
65 |
|
66 |
return $collection;
|
67 |
}
|
71 |
*/
|
72 |
public function applyToCollection($collection)
|
73 |
{
|
74 |
+
$values = $this->getMSelectedValues();
|
75 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
76 |
+
if (!method_exists($engine, 'getSearchEngineFieldName')) {
|
77 |
+
$labels = array();
|
78 |
+
foreach ($values as $value) {
|
79 |
+
$labels[] = $this->getAttributeModel()->getFrontend()->getOption($value);
|
80 |
+
}
|
81 |
+
$values = $labels;
|
82 |
+
}
|
83 |
+
$collection->addFqFilter(array($this->getFilterField() => array('or' => $values)));
|
84 |
}
|
85 |
|
86 |
}
|
app/code/local/Mana/Filters/Model/Solr/Category.php
CHANGED
@@ -15,11 +15,26 @@ class Mana_Filters_Model_Solr_Category extends Mana_Filters_Model_Filter_Categor
|
|
15 |
return true;
|
16 |
}
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
public function processCounts($counts) {
|
19 |
/* @var $collection Enterprise_Search_Model_Resource_Collection */
|
20 |
$collection = $counts;
|
21 |
|
22 |
-
$facetedData = $collection->getFacetedData(
|
23 |
foreach ($this->getCountedCategories() as $category) {
|
24 |
if (isset($facetedData[$category->getId()])) {
|
25 |
$category->setProductCount($facetedData[$category->getId()]);
|
@@ -42,7 +57,7 @@ class Mana_Filters_Model_Solr_Category extends Mana_Filters_Model_Filter_Categor
|
|
42 |
? array_keys($this->getCountedCategories())
|
43 |
: array_keys($this->getCountedCategories()->toArray()));
|
44 |
|
45 |
-
$collection->setFacetCondition(
|
46 |
|
47 |
return $collection;
|
48 |
}
|
@@ -52,7 +67,7 @@ class Mana_Filters_Model_Solr_Category extends Mana_Filters_Model_Filter_Categor
|
|
52 |
*/
|
53 |
public function applyToCollection($collection)
|
54 |
{
|
55 |
-
$collection->addFqFilter(array(
|
56 |
}
|
57 |
|
58 |
public function isFilterAppliedWhenCounting($modelToBeApplied) {
|
15 |
return true;
|
16 |
}
|
17 |
|
18 |
+
/**
|
19 |
+
* Get facet field name based on current website and customer group
|
20 |
+
*
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
protected function _getFilterField() {
|
24 |
+
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
25 |
+
if (method_exists($engine, 'getSearchEngineFieldName')) {
|
26 |
+
return 'category_ids';
|
27 |
+
}
|
28 |
+
else {
|
29 |
+
return 'categories';
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
public function processCounts($counts) {
|
34 |
/* @var $collection Enterprise_Search_Model_Resource_Collection */
|
35 |
$collection = $counts;
|
36 |
|
37 |
+
$facetedData = $collection->getFacetedData($this->_getFilterField());
|
38 |
foreach ($this->getCountedCategories() as $category) {
|
39 |
if (isset($facetedData[$category->getId()])) {
|
40 |
$category->setProductCount($facetedData[$category->getId()]);
|
57 |
? array_keys($this->getCountedCategories())
|
58 |
: array_keys($this->getCountedCategories()->toArray()));
|
59 |
|
60 |
+
$collection->setFacetCondition($this->_getFilterField(), $categories);
|
61 |
|
62 |
return $collection;
|
63 |
}
|
67 |
*/
|
68 |
public function applyToCollection($collection)
|
69 |
{
|
70 |
+
$collection->addFqFilter(array($this->_getFilterField() => array('or' => $this->getMSelectedValues())));
|
71 |
}
|
72 |
|
73 |
public function isFilterAppliedWhenCounting($modelToBeApplied) {
|
app/code/local/Mana/Filters/Model/Solr/Decimal.php
CHANGED
@@ -72,12 +72,14 @@ class Mana_Filters_Model_Solr_Decimal extends Mana_Filters_Model_Filter_Decimal
|
|
72 |
|
73 |
$fq = array();
|
74 |
foreach ($this->getMSelectedValues() as $selection) {
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
81 |
}
|
82 |
|
83 |
$collection->addFqFilter(array($field => array('or' => $fq)));
|
72 |
|
73 |
$fq = array();
|
74 |
foreach ($this->getMSelectedValues() as $selection) {
|
75 |
+
if (strpos($selection, ',') !== false) {
|
76 |
+
list($index, $range) = explode(',', $selection);
|
77 |
+
$range = $this->_getResource()->getRange($index, $range);
|
78 |
+
$fq[] = array(
|
79 |
+
'from' => $range['from'],
|
80 |
+
'to' => $range['to'] - ($this->isUpperBoundInclusive() ? 0 : 0.001),
|
81 |
+
);
|
82 |
+
}
|
83 |
}
|
84 |
|
85 |
$collection->addFqFilter(array($field => array('or' => $fq)));
|
app/code/local/Mana/Filters/Model/Solr/Price.php
CHANGED
@@ -26,7 +26,7 @@ class Mana_Filters_Model_Solr_Price extends Mana_Filters_Model_Filter_Price
|
|
26 |
*/
|
27 |
public function countOnCollection($collection)
|
28 |
{
|
29 |
-
if (Mage::app()->getStore()->getConfig(self::XML_PATH_RANGE_CALCULATION) ==
|
30 |
return $this->_addCalculatedFacetConditionToCollection($collection);
|
31 |
}
|
32 |
|
@@ -79,17 +79,19 @@ class Mana_Filters_Model_Solr_Price extends Mana_Filters_Model_Filter_Price
|
|
79 |
$field = $this->_getFilterField();
|
80 |
$fq = array();
|
81 |
foreach ($this->getMSelectedValues() as $selection) {
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
$to
|
87 |
-
|
|
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
93 |
}
|
94 |
|
95 |
$collection->addFqFilter(array($field => array('or' => $fq)));
|
@@ -120,7 +122,14 @@ class Mana_Filters_Model_Solr_Price extends Mana_Filters_Model_Filter_Price
|
|
120 |
protected function _getFilterField()
|
121 |
{
|
122 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
return $priceField;
|
126 |
}
|
@@ -274,7 +283,7 @@ class Mana_Filters_Model_Solr_Price extends Mana_Filters_Model_Filter_Price
|
|
274 |
|
275 |
$max = $stats[$this->_getFilterField()]['max'];
|
276 |
if (!is_numeric($max)) {
|
277 |
-
|
278 |
} else {
|
279 |
$max = floor($max * $this->getCurrencyRate());
|
280 |
}
|
26 |
*/
|
27 |
public function countOnCollection($collection)
|
28 |
{
|
29 |
+
if (Mage::app()->getStore()->getConfig(self::XML_PATH_RANGE_CALCULATION) == 'improved') {
|
30 |
return $this->_addCalculatedFacetConditionToCollection($collection);
|
31 |
}
|
32 |
|
79 |
$field = $this->_getFilterField();
|
80 |
$fq = array();
|
81 |
foreach ($this->getMSelectedValues() as $selection) {
|
82 |
+
if (strpos($selection, ',') !== false) {
|
83 |
+
list($index, $range) = explode(',', $selection);
|
84 |
+
$range = $this->_getResource()->getPriceRange($index, $range);
|
85 |
+
$to = $range['to'];
|
86 |
+
if ($to < $this->getMaxPriceInt() && !$this->isUpperBoundInclusive()) {
|
87 |
+
$to -= 0.001;
|
88 |
+
}
|
89 |
|
90 |
+
$fq[] = array(
|
91 |
+
'from' => $range['from'],
|
92 |
+
'to' => $to,
|
93 |
+
);
|
94 |
+
}
|
95 |
}
|
96 |
|
97 |
$collection->addFqFilter(array($field => array('or' => $fq)));
|
122 |
protected function _getFilterField()
|
123 |
{
|
124 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
125 |
+
if (method_exists($engine, 'getSearchEngineFieldName')) {
|
126 |
+
$priceField = $engine->getSearchEngineFieldName('price');
|
127 |
+
}
|
128 |
+
else {
|
129 |
+
$websiteId = Mage::app()->getStore()->getWebsiteId();
|
130 |
+
$customerGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
|
131 |
+
$priceField = 'price_' . $customerGroupId . '_' . $websiteId;
|
132 |
+
}
|
133 |
|
134 |
return $priceField;
|
135 |
}
|
283 |
|
284 |
$max = $stats[$this->_getFilterField()]['max'];
|
285 |
if (!is_numeric($max)) {
|
286 |
+
return parent::getRangeOnCollection($collection);
|
287 |
} else {
|
288 |
$max = floor($max * $this->getCurrencyRate());
|
289 |
}
|
app/code/local/Mana/Filters/Model/Solr/Reverse/Attribute.php
CHANGED
@@ -17,8 +17,7 @@ class Mana_Filters_Model_Solr_Reverse_Attribute extends Mana_Filters_Model_Solr_
|
|
17 |
public function applyToCollection($collection)
|
18 |
{
|
19 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
20 |
-
$
|
21 |
-
$collection->addFqFilter(array($facetField => array('reverse' => $this->getMSelectedValues())));
|
22 |
}
|
23 |
|
24 |
}
|
17 |
public function applyToCollection($collection)
|
18 |
{
|
19 |
$engine = Mage::getResourceSingleton('enterprise_search/engine');
|
20 |
+
$collection->addFqFilter(array($this->getFilterField() => array('reverse' => $this->getMSelectedValues())));
|
|
|
21 |
}
|
22 |
|
23 |
}
|
app/code/local/Mana/Filters/Model/Solr/Reverse/Decimal.php
CHANGED
@@ -21,11 +21,13 @@ class Mana_Filters_Model_Solr_Reverse_Decimal extends Mana_Filters_Model_Solr_De
|
|
21 |
|
22 |
$fq = array();
|
23 |
foreach ($this->getMSelectedValues() as $selection) {
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
29 |
}
|
30 |
|
31 |
$collection->addFqFilter(array($field => array('reverse' => $fq)));
|
21 |
|
22 |
$fq = array();
|
23 |
foreach ($this->getMSelectedValues() as $selection) {
|
24 |
+
if (strpos($selection, ',') !== false) {
|
25 |
+
list($index, $range) = explode(',', $selection);
|
26 |
+
$fq[] = array(
|
27 |
+
'from' => ($range * ($index - 1)),
|
28 |
+
'to' => $range * $index - ($this->isUpperBoundInclusive() ? 0 : 0.001),
|
29 |
+
);
|
30 |
+
}
|
31 |
}
|
32 |
|
33 |
$collection->addFqFilter(array($field => array('reverse' => $fq)));
|
app/code/local/Mana/Filters/Model/Solr/Reverse/Price.php
CHANGED
@@ -22,16 +22,18 @@ class Mana_Filters_Model_Solr_Reverse_Price extends Mana_Filters_Model_Solr_Pric
|
|
22 |
$field = $this->_getFilterField();
|
23 |
$fq = array();
|
24 |
foreach ($this->getMSelectedValues() as $selection) {
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
$to
|
29 |
-
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
35 |
}
|
36 |
|
37 |
$collection->addFqFilter(array($field => array('reverse' => $fq)));
|
22 |
$field = $this->_getFilterField();
|
23 |
$fq = array();
|
24 |
foreach ($this->getMSelectedValues() as $selection) {
|
25 |
+
if (strpos($selection, ',') !== false) {
|
26 |
+
list($index, $range) = explode(',', $selection);
|
27 |
+
$to = $range * $index;
|
28 |
+
if ($to < $this->getMaxPriceInt() && !$this->isUpperBoundInclusive()) {
|
29 |
+
$to -= 0.001;
|
30 |
+
}
|
31 |
|
32 |
+
$fq[] = array(
|
33 |
+
'from' => ($range * ($index - 1)),
|
34 |
+
'to' => $to,
|
35 |
+
);
|
36 |
+
}
|
37 |
}
|
38 |
|
39 |
$collection->addFqFilter(array($field => array('reverse' => $fq)));
|
app/code/local/Mana/Filters/Resource/Filter/Decimal.php
CHANGED
@@ -62,25 +62,27 @@ class Mana_Filters_Resource_Filter_Decimal extends Mage_Catalog_Model_Resource_E
|
|
62 |
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId())
|
63 |
);
|
64 |
|
65 |
-
$collection->getSelect()->join(
|
66 |
-
array($tableAlias => $this->getMainTable()),
|
67 |
-
join(' AND ', $conditions),
|
68 |
-
array()
|
69 |
-
);
|
70 |
-
|
71 |
-
// MANA BEGIN: modify select formation to include multiple price ranges
|
72 |
$condition = '';
|
73 |
foreach ($value as $selection) {
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
-
$collection->getSelect()
|
81 |
-
->distinct()
|
82 |
-
->where($condition);
|
83 |
-
// MANA END
|
84 |
|
85 |
return $this;
|
86 |
}
|
@@ -122,7 +124,7 @@ class Mana_Filters_Resource_Filter_Decimal extends Mage_Catalog_Model_Resource_E
|
|
122 |
*/
|
123 |
public function getMinMaxForCollection($filter, $collection)
|
124 |
{
|
125 |
-
$select = $this->
|
126 |
$connection = $this->_getReadAdapter();
|
127 |
|
128 |
$table = 'decimal_index';
|
62 |
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId())
|
63 |
);
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
$condition = '';
|
66 |
foreach ($value as $selection) {
|
67 |
+
if (strpos($selection, ',') !== false) {
|
68 |
+
list($index, $range) = explode(',', $selection);
|
69 |
+
$range = $this->getRange($index, $range);
|
70 |
+
if ($condition != '') $condition .= ' OR ';
|
71 |
+
$condition .= '(('."{$tableAlias}.value" . ' >= '. $range['from'].') '.
|
72 |
+
'AND ('."{$tableAlias}.value" . ($this->isUpperBoundInclusive() ? ' <= ' : ' < '). $range['to'].'))';
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
if ($condition) {
|
77 |
+
$collection->getSelect()
|
78 |
+
->join(
|
79 |
+
array($tableAlias => $this->getMainTable()),
|
80 |
+
join(' AND ', $conditions),
|
81 |
+
array()
|
82 |
+
)
|
83 |
+
->distinct()
|
84 |
+
->where($condition);
|
85 |
}
|
|
|
|
|
|
|
|
|
86 |
|
87 |
return $this;
|
88 |
}
|
124 |
*/
|
125 |
public function getMinMaxForCollection($filter, $collection)
|
126 |
{
|
127 |
+
$select = $this->_getSelectForCollection($filter, $collection);
|
128 |
$connection = $this->_getReadAdapter();
|
129 |
|
130 |
$table = 'decimal_index';
|
app/code/local/Mana/Filters/Resource/Filter/Price.php
CHANGED
@@ -25,14 +25,11 @@ class Mana_Filters_Resource_Filter_Price extends Mage_Catalog_Model_Resource_Eav
|
|
25 |
{
|
26 |
$collection->addPriceData($filter->getCustomerGroupId(), $filter->getWebsiteId());
|
27 |
|
28 |
-
|
29 |
-
$select = clone $collection->getCatalogPreparedSelect();
|
30 |
-
} else {
|
31 |
-
$select = clone $collection->getSelect();
|
32 |
-
}
|
33 |
|
34 |
// reset columns, order and limitation conditions
|
35 |
$select->reset(Zend_Db_Select::COLUMNS);
|
|
|
36 |
$select->reset(Zend_Db_Select::ORDER);
|
37 |
$select->reset(Zend_Db_Select::LIMIT_COUNT);
|
38 |
$select->reset(Zend_Db_Select::LIMIT_OFFSET);
|
@@ -100,15 +97,15 @@ class Mana_Filters_Resource_Filter_Price extends Mage_Catalog_Model_Resource_Eav
|
|
100 |
if (Mage::helper('mana_core')->isMageVersionEqualOrGreater('1.7')) {
|
101 |
$table = Mage_Catalog_Model_Resource_Product_Collection::MAIN_TABLE_ALIAS;
|
102 |
$select = $this->_getSelectOnCollection($collection, $model);
|
103 |
-
$
|
|
|
104 |
|
105 |
$range = floatval($model->getPriceRange());
|
106 |
if ($range == 0) {
|
107 |
$range = 1;
|
108 |
}
|
109 |
-
$fix = $this->_getConfigurablePriceFix();
|
110 |
$countExpr = new Zend_Db_Expr('COUNT(*)');
|
111 |
-
$rangeExpr = new Zend_Db_Expr("FLOOR(({$priceExpression}
|
112 |
|
113 |
$select->columns(array(
|
114 |
'range' => $rangeExpr,
|
@@ -119,6 +116,8 @@ class Mana_Filters_Resource_Filter_Price extends Mage_Catalog_Model_Resource_Eav
|
|
119 |
Mage::helper('mana_filters')->resetProductCollectionWhereClause($select);
|
120 |
$select->where("{$table}.min_price > 0");
|
121 |
|
|
|
|
|
122 |
return $this->_getReadAdapter()->fetchPairs($select);
|
123 |
}
|
124 |
else {
|
@@ -174,15 +173,20 @@ class Mana_Filters_Resource_Filter_Price extends Mage_Catalog_Model_Resource_Eav
|
|
174 |
|
175 |
$condition = '';
|
176 |
foreach ($model->getMSelectedValues() as $selection) {
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
}
|
183 |
-
$select
|
184 |
-
->distinct()
|
185 |
-
->where($condition);
|
186 |
return $this;
|
187 |
}
|
188 |
|
@@ -201,21 +205,19 @@ class Mana_Filters_Resource_Filter_Price extends Mage_Catalog_Model_Resource_Eav
|
|
201 |
{
|
202 |
$select = $this->_getSelectOnCollection($collection, $filter);
|
203 |
$connection = $this->_getReadAdapter();
|
204 |
-
$response = $this->_dispatchPreparePriceEvent($filter, $select);
|
205 |
|
206 |
if (Mage::helper('mana_core')->isMageVersionEqualOrGreater('1.7')) {
|
207 |
-
$
|
208 |
-
$additional = $this->_replaceTableAlias(join('', $response->getAdditionalCalculations()));
|
209 |
}
|
210 |
else {
|
|
|
211 |
$table = $this->_getIndexTableAlias();
|
212 |
$additional = join('', $response->getAdditionalCalculations());
|
|
|
|
|
213 |
}
|
214 |
|
215 |
-
|
216 |
-
$maxPriceExpr = new Zend_Db_Expr("MAX({$table}.min_price {$additional} {$fix}) AS m_max_price");
|
217 |
-
|
218 |
-
Mage::helper('mana_filters')->resetProductCollectionWhereClause($select);
|
219 |
$select->columns(array($maxPriceExpr))->order('m_max_price DESC');
|
220 |
|
221 |
$result = $connection->fetchOne($select) * $filter->getCurrencyRate();
|
@@ -255,4 +257,49 @@ class Mana_Filters_Resource_Filter_Price extends Mage_Catalog_Model_Resource_Eav
|
|
255 |
}
|
256 |
return $subSelect ? " + COALESCE(($subSelect), 0)" : '';
|
257 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
}
|
25 |
{
|
26 |
$collection->addPriceData($filter->getCustomerGroupId(), $filter->getWebsiteId());
|
27 |
|
28 |
+
$select = clone $collection->getSelect();
|
|
|
|
|
|
|
|
|
29 |
|
30 |
// reset columns, order and limitation conditions
|
31 |
$select->reset(Zend_Db_Select::COLUMNS);
|
32 |
+
$select->reset(Zend_Db_Select::GROUP);
|
33 |
$select->reset(Zend_Db_Select::ORDER);
|
34 |
$select->reset(Zend_Db_Select::LIMIT_COUNT);
|
35 |
$select->reset(Zend_Db_Select::LIMIT_OFFSET);
|
97 |
if (Mage::helper('mana_core')->isMageVersionEqualOrGreater('1.7')) {
|
98 |
$table = Mage_Catalog_Model_Resource_Product_Collection::MAIN_TABLE_ALIAS;
|
99 |
$select = $this->_getSelectOnCollection($collection, $model);
|
100 |
+
$rate = $model->getCurrencyRate();
|
101 |
+
$priceExpression = "({$this->_getPriceExpression($model, $select)}) * {$rate}";
|
102 |
|
103 |
$range = floatval($model->getPriceRange());
|
104 |
if ($range == 0) {
|
105 |
$range = 1;
|
106 |
}
|
|
|
107 |
$countExpr = new Zend_Db_Expr('COUNT(*)');
|
108 |
+
$rangeExpr = new Zend_Db_Expr("FLOOR(({$priceExpression}) / {$range}) + 1");
|
109 |
|
110 |
$select->columns(array(
|
111 |
'range' => $rangeExpr,
|
116 |
Mage::helper('mana_filters')->resetProductCollectionWhereClause($select);
|
117 |
$select->where("{$table}.min_price > 0");
|
118 |
|
119 |
+
//Mage::log($select->__toString(), Zend_Log::DEBUG, 'price.log' );
|
120 |
+
//Mage::log(json_encode($this->_getReadAdapter()->fetchPairs($select)), Zend_Log::DEBUG, 'price.log' );
|
121 |
return $this->_getReadAdapter()->fetchPairs($select);
|
122 |
}
|
123 |
else {
|
173 |
|
174 |
$condition = '';
|
175 |
foreach ($model->getMSelectedValues() as $selection) {
|
176 |
+
if (strpos($selection, ',') !== false) {
|
177 |
+
list($index, $range) = explode(',', $selection);
|
178 |
+
$range = $this->getPriceRange($index, $range);
|
179 |
+
if ($condition != '') $condition .= ' OR ';
|
180 |
+
$condition .= '(('.$priceExpr . ' >= '. $range['from'].') '.
|
181 |
+
'AND ('.$priceExpr . ($this->isUpperBoundInclusive() ? ' <= ' : ' < '). $range['to'].'))';
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
if ($condition) {
|
186 |
+
$select
|
187 |
+
->distinct()
|
188 |
+
->where($condition);
|
189 |
}
|
|
|
|
|
|
|
190 |
return $this;
|
191 |
}
|
192 |
|
205 |
{
|
206 |
$select = $this->_getSelectOnCollection($collection, $filter);
|
207 |
$connection = $this->_getReadAdapter();
|
|
|
208 |
|
209 |
if (Mage::helper('mana_core')->isMageVersionEqualOrGreater('1.7')) {
|
210 |
+
$maxPriceExpr = new Zend_Db_Expr("MAX({$this->_getPriceExpression($filter, $select)}) AS m_max_price");
|
|
|
211 |
}
|
212 |
else {
|
213 |
+
$response = $this->_dispatchPreparePriceEvent($filter, $select);
|
214 |
$table = $this->_getIndexTableAlias();
|
215 |
$additional = join('', $response->getAdditionalCalculations());
|
216 |
+
$fix = $this->_getConfigurablePriceFix();
|
217 |
+
$maxPriceExpr = new Zend_Db_Expr("MAX({$table}.min_price {$additional} {$fix}) AS m_max_price");
|
218 |
}
|
219 |
|
220 |
+
//Mage::helper('mana_filters')->resetProductCollectionWhereClause($select);
|
|
|
|
|
|
|
221 |
$select->columns(array($maxPriceExpr))->order('m_max_price DESC');
|
222 |
|
223 |
$result = $connection->fetchOne($select) * $filter->getCurrencyRate();
|
257 |
}
|
258 |
return $subSelect ? " + COALESCE(($subSelect), 0)" : '';
|
259 |
}
|
260 |
+
|
261 |
+
protected $_preparedExpressions = array();
|
262 |
+
|
263 |
+
protected function _getPriceExpression($filter, $select, $replaceAlias = true) {
|
264 |
+
foreach ($this->_preparedExpressions as $expr) {
|
265 |
+
if ($expr['select'] == $select) {
|
266 |
+
return $expr['result'];
|
267 |
+
}
|
268 |
+
}
|
269 |
+
|
270 |
+
$response = new Varien_Object();
|
271 |
+
$response->setAdditionalCalculations(array());
|
272 |
+
$tableAliases = array_keys($select->getPart(Zend_Db_Select::FROM));
|
273 |
+
if (in_array(Mage_Catalog_Model_Resource_Product_Collection::INDEX_TABLE_ALIAS, $tableAliases)) {
|
274 |
+
$table = Mage_Catalog_Model_Resource_Product_Collection::INDEX_TABLE_ALIAS;
|
275 |
+
}
|
276 |
+
else {
|
277 |
+
$table = reset($tableAliases);
|
278 |
+
}
|
279 |
+
|
280 |
+
// prepare event arguments
|
281 |
+
$eventArgs = array(
|
282 |
+
'select' => $select,
|
283 |
+
'table' => $table,
|
284 |
+
'store_id' => $filter->getStoreId(),
|
285 |
+
'response_object' => $response
|
286 |
+
);
|
287 |
+
|
288 |
+
Mage::dispatchEvent('catalog_prepare_price_select', $eventArgs);
|
289 |
+
|
290 |
+
$table = Mage_Catalog_Model_Resource_Product_Collection::MAIN_TABLE_ALIAS;
|
291 |
+
$additional = $this->_replaceTableAlias(join('', $response->getAdditionalCalculations()));
|
292 |
+
|
293 |
+
$fix = $this->_getConfigurablePriceFix();
|
294 |
+
$result = "{$table}.min_price {$additional} {$fix}";
|
295 |
+
|
296 |
+
if ($replaceAlias) {
|
297 |
+
$result = $this->_replaceTableAlias($result);
|
298 |
+
}
|
299 |
+
|
300 |
+
$this->_preparedExpressions[] = compact('select', 'result');
|
301 |
+
|
302 |
+
return $result;
|
303 |
+
}
|
304 |
+
|
305 |
}
|
app/code/local/Mana/Filters/Resource/Filter/Reverse/Decimal.php
CHANGED
@@ -28,25 +28,27 @@ class Mana_Filters_Resource_Filter_Reverse_Decimal extends Mana_Filters_Resource
|
|
28 |
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId())
|
29 |
);
|
30 |
|
31 |
-
$collection->getSelect()->join(
|
32 |
-
array($tableAlias => $this->getMainTable()),
|
33 |
-
join(' AND ', $conditions),
|
34 |
-
array()
|
35 |
-
);
|
36 |
-
|
37 |
-
// MANA BEGIN: modify select formation to include multiple price ranges
|
38 |
$condition = '';
|
39 |
foreach ($value as $selection) {
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
46 |
-
$collection->getSelect()
|
47 |
-
->distinct()
|
48 |
-
->where("NOT ($condition)");
|
49 |
-
// MANA END
|
50 |
|
51 |
return $this;
|
52 |
}
|
28 |
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId())
|
29 |
);
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
$condition = '';
|
32 |
foreach ($value as $selection) {
|
33 |
+
if (strpos($selection, ',') !== false) {
|
34 |
+
list($index, $range) = explode(',', $selection);
|
35 |
+
$range = $this->getRange($index, $range);
|
36 |
+
if ($condition != '') $condition .= ' OR ';
|
37 |
+
$condition .= '(('."{$tableAlias}.value" . ' >= '. $range['from'].') '.
|
38 |
+
'AND ('."{$tableAlias}.value" . ($this->isUpperBoundInclusive() ? ' <= ' : ' < '). $range['to'].'))';
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
if ($condition) {
|
43 |
+
$collection->getSelect()
|
44 |
+
->join(
|
45 |
+
array($tableAlias => $this->getMainTable()),
|
46 |
+
join(' AND ', $conditions),
|
47 |
+
array()
|
48 |
+
)
|
49 |
+
->distinct()
|
50 |
+
->where("NOT ($condition)");
|
51 |
}
|
|
|
|
|
|
|
|
|
52 |
|
53 |
return $this;
|
54 |
}
|
app/code/local/Mana/Filters/Resource/Filter/Reverse/Price.php
CHANGED
@@ -38,15 +38,20 @@ class Mana_Filters_Resource_Filter_Reverse_Price extends Mana_Filters_Resource_F
|
|
38 |
|
39 |
$condition = '';
|
40 |
foreach ($model->getMSelectedValues() as $selection) {
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
-
$select
|
48 |
-
->distinct()
|
49 |
-
->where("NOT ($condition)");
|
50 |
return $this;
|
51 |
}
|
52 |
|
38 |
|
39 |
$condition = '';
|
40 |
foreach ($model->getMSelectedValues() as $selection) {
|
41 |
+
if (strpos($selection, ',') !== false) {
|
42 |
+
list($index, $range) = explode(',', $selection);
|
43 |
+
$range = $this->getPriceRange($index, $range);
|
44 |
+
if ($condition != '') $condition .= ' OR ';
|
45 |
+
$condition .= '(('.$priceExpr . ' >= '. $range['from'].') '.
|
46 |
+
'AND ('.$priceExpr . ($this->isUpperBoundInclusive() ? ' <= ' : ' < '). $range['to'].'))';
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
if ($condition) {
|
51 |
+
$select
|
52 |
+
->distinct()
|
53 |
+
->where("NOT ($condition)");
|
54 |
}
|
|
|
|
|
|
|
55 |
return $this;
|
56 |
}
|
57 |
|
app/code/local/Mana/Filters/Resource/Filter2.php
CHANGED
@@ -53,6 +53,12 @@ class Mana_Filters_Resource_Filter2 extends Mana_Db_Resource_Object {
|
|
53 |
const DM_HELP_WIDTH = 33;
|
54 |
|
55 |
const DM_IS_REVERSE = 34;
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
#endregion
|
57 |
|
58 |
/**
|
@@ -161,6 +167,9 @@ class Mana_Filters_Resource_Filter2 extends Mana_Db_Resource_Object {
|
|
161 |
if (!Mage::helper('mana_db')->hasOverriddenValue($object, $values, Mana_Filters_Resource_Filter2::DM_SORT_METHOD)) {
|
162 |
$object->setSortMethod(Mage::helper('mana_db')->getLatestConfig('mana_filters/display/sort_method'));
|
163 |
}
|
|
|
|
|
|
|
164 |
}
|
165 |
|
166 |
/**
|
@@ -238,6 +247,7 @@ class Mana_Filters_Resource_Filter2 extends Mana_Db_Resource_Object {
|
|
238 |
$object->setIsEnabledInSearch($values['is_enabled_in_search']);
|
239 |
$object->setPosition($values['position']);
|
240 |
$object->setSortMethod(Mage::helper('mana_db')->getLatestConfig('mana_filters/display/sort_method'));
|
|
|
241 |
}
|
242 |
/**
|
243 |
* Enter description here ...
|
@@ -265,6 +275,8 @@ class Mana_Filters_Resource_Filter2 extends Mana_Db_Resource_Object {
|
|
265 |
'target.code = eav_attribute.attribute_code'.$attributeJoin, null)
|
266 |
->joinLeft(array('eav_attribute_additional' => Mage::getSingleton('core/resource')->getTableName('catalog/eav_attribute')),
|
267 |
'eav_attribute.attribute_id = eav_attribute_additional.attribute_id', null)
|
|
|
|
|
268 |
->distinct()
|
269 |
->where('(eav_attribute.attribute_id IS NULL) OR (eav_attribute_additional.is_filterable = 0)')
|
270 |
->where("target.code <> 'category'");
|
@@ -292,6 +304,7 @@ class Mana_Filters_Resource_Filter2 extends Mana_Db_Resource_Object {
|
|
292 |
Mage::helper('mana_db')->updateDefaultableField($object, 'sort_method', Mana_Filters_Resource_Filter2::DM_SORT_METHOD, $fields, $useDefault);
|
293 |
Mage::helper('mana_db')->updateDefaultableField($object, 'operation', Mana_Filters_Resource_Filter2::DM_OPERATION, $fields, $useDefault);
|
294 |
Mage::helper('mana_db')->updateDefaultableField($object, 'is_reverse', Mana_Filters_Resource_Filter2::DM_IS_REVERSE, $fields, $useDefault);
|
|
|
295 |
}
|
296 |
protected function _afterSave(Mage_Core_Model_Abstract $object) {
|
297 |
if ($edit = $object->getValueData()) {
|
53 |
const DM_HELP_WIDTH = 33;
|
54 |
|
55 |
const DM_IS_REVERSE = 34;
|
56 |
+
|
57 |
+
const DM_INCLUDE_IN_URL = 35;
|
58 |
+
const DM_URL_POSITION = 36;
|
59 |
+
|
60 |
+
const DM_DISABLE_NO_RESULT_OPTIONS = 37;
|
61 |
+
|
62 |
#endregion
|
63 |
|
64 |
/**
|
167 |
if (!Mage::helper('mana_db')->hasOverriddenValue($object, $values, Mana_Filters_Resource_Filter2::DM_SORT_METHOD)) {
|
168 |
$object->setSortMethod(Mage::helper('mana_db')->getLatestConfig('mana_filters/display/sort_method'));
|
169 |
}
|
170 |
+
if (!Mage::helper('mana_db')->hasOverriddenValue($object, $values, Mana_Filters_Resource_Filter2::DM_DISABLE_NO_RESULT_OPTIONS)) {
|
171 |
+
$object->setDisableNoResultOptions(Mage::helper('mana_db')->getLatestConfig('mana_filters/display/disable_no_result_options'));
|
172 |
+
}
|
173 |
}
|
174 |
|
175 |
/**
|
247 |
$object->setIsEnabledInSearch($values['is_enabled_in_search']);
|
248 |
$object->setPosition($values['position']);
|
249 |
$object->setSortMethod(Mage::helper('mana_db')->getLatestConfig('mana_filters/display/sort_method'));
|
250 |
+
$object->setDisableNoResultOptions(Mage::helper('mana_db')->getLatestConfig('mana_filters/display/disable_no_result_options'));
|
251 |
}
|
252 |
/**
|
253 |
* Enter description here ...
|
275 |
'target.code = eav_attribute.attribute_code'.$attributeJoin, null)
|
276 |
->joinLeft(array('eav_attribute_additional' => Mage::getSingleton('core/resource')->getTableName('catalog/eav_attribute')),
|
277 |
'eav_attribute.attribute_id = eav_attribute_additional.attribute_id', null)
|
278 |
+
->joinLeft(array('eav_entity_type' => Mage::getSingleton('core/resource')->getTableName('eav/entity_type')),
|
279 |
+
"eav_entity_type.entity_type_id = eav_attribute.entity_type_id AND eav_entity_type.entity_type_code = 'catalog_product'", null)
|
280 |
->distinct()
|
281 |
->where('(eav_attribute.attribute_id IS NULL) OR (eav_attribute_additional.is_filterable = 0)')
|
282 |
->where("target.code <> 'category'");
|
304 |
Mage::helper('mana_db')->updateDefaultableField($object, 'sort_method', Mana_Filters_Resource_Filter2::DM_SORT_METHOD, $fields, $useDefault);
|
305 |
Mage::helper('mana_db')->updateDefaultableField($object, 'operation', Mana_Filters_Resource_Filter2::DM_OPERATION, $fields, $useDefault);
|
306 |
Mage::helper('mana_db')->updateDefaultableField($object, 'is_reverse', Mana_Filters_Resource_Filter2::DM_IS_REVERSE, $fields, $useDefault);
|
307 |
+
Mage::helper('mana_db')->updateDefaultableField($object, 'disable_no_result_options', Mana_Filters_Resource_Filter2::DM_DISABLE_NO_RESULT_OPTIONS, $fields, $useDefault);
|
308 |
}
|
309 |
protected function _afterSave(Mage_Core_Model_Abstract $object) {
|
310 |
if ($edit = $object->getValueData()) {
|
app/code/local/Mana/Filters/Resource/Filter2/Store.php
CHANGED
@@ -53,6 +53,7 @@ class Mana_Filters_Resource_Filter2_Store extends Mana_Filters_Resource_Filter2
|
|
53 |
'global.sort_method AS sort_method',
|
54 |
'global.operation AS operation',
|
55 |
'global.is_reverse AS is_reverse',
|
|
|
56 |
));
|
57 |
if ($options['trackKeys']) {
|
58 |
if (($keys = $options['targets'][$globalEntityName]->getSavedKeys()) && count($keys)) {
|
@@ -107,6 +108,9 @@ class Mana_Filters_Resource_Filter2_Store extends Mana_Filters_Resource_Filter2
|
|
107 |
if (!Mage::helper('mana_db')->hasOverriddenValue($object, $values, Mana_Filters_Resource_Filter2::DM_IS_REVERSE)) {
|
108 |
$object->setIsReverse($values['is_reverse']);
|
109 |
}
|
|
|
|
|
|
|
110 |
}
|
111 |
/**
|
112 |
* Enter description here ...
|
@@ -137,6 +141,7 @@ class Mana_Filters_Resource_Filter2_Store extends Mana_Filters_Resource_Filter2
|
|
137 |
'global.sort_method AS sort_method',
|
138 |
'global.operation AS operation',
|
139 |
'global.is_reverse AS is_reverse',
|
|
|
140 |
));
|
141 |
if ($options['trackKeys']) {
|
142 |
if (($keys = $options['targets'][$globalEntityName]->getSavedKeys()) && count($keys)) {
|
@@ -170,6 +175,7 @@ class Mana_Filters_Resource_Filter2_Store extends Mana_Filters_Resource_Filter2
|
|
170 |
$object->setSortMethod($values['sort_method']);
|
171 |
$object->setOperation($values['operation']);
|
172 |
$object->setIsReverse($values['is_reverse']);
|
|
|
173 |
}
|
174 |
/**
|
175 |
* Enter description here ...
|
53 |
'global.sort_method AS sort_method',
|
54 |
'global.operation AS operation',
|
55 |
'global.is_reverse AS is_reverse',
|
56 |
+
'global.disable_no_result_options AS disable_no_result_options',
|
57 |
));
|
58 |
if ($options['trackKeys']) {
|
59 |
if (($keys = $options['targets'][$globalEntityName]->getSavedKeys()) && count($keys)) {
|
108 |
if (!Mage::helper('mana_db')->hasOverriddenValue($object, $values, Mana_Filters_Resource_Filter2::DM_IS_REVERSE)) {
|
109 |
$object->setIsReverse($values['is_reverse']);
|
110 |
}
|
111 |
+
if (!Mage::helper('mana_db')->hasOverriddenValue($object, $values, Mana_Filters_Resource_Filter2::DM_DISABLE_NO_RESULT_OPTIONS)) {
|
112 |
+
$object->setDisableNoResultOptions($values['disable_no_result_options']);
|
113 |
+
}
|
114 |
}
|
115 |
/**
|
116 |
* Enter description here ...
|
141 |
'global.sort_method AS sort_method',
|
142 |
'global.operation AS operation',
|
143 |
'global.is_reverse AS is_reverse',
|
144 |
+
'global.disable_no_result_options AS disable_no_result_options',
|
145 |
));
|
146 |
if ($options['trackKeys']) {
|
147 |
if (($keys = $options['targets'][$globalEntityName]->getSavedKeys()) && count($keys)) {
|
175 |
$object->setSortMethod($values['sort_method']);
|
176 |
$object->setOperation($values['operation']);
|
177 |
$object->setIsReverse($values['is_reverse']);
|
178 |
+
$object->setDisableNoResultOptions($values['disable_no_result_options']);
|
179 |
}
|
180 |
/**
|
181 |
* Enter description here ...
|
app/code/local/Mana/Filters/Resource/Filter2/Value.php
CHANGED
@@ -22,8 +22,32 @@ class Mana_Filters_Resource_Filter2_Value extends Mana_Db_Resource_Object {
|
|
22 |
const DM_NORMAL_HOVERED_IMAGE = 5;
|
23 |
const DM_SELECTED_HOVERED_IMAGE = 6;
|
24 |
const DM_STATE_IMAGE = 7;
|
|
|
25 |
#endregion
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
/**
|
28 |
* Invoked during resource model creation process, this method associates this resource model with model class
|
29 |
* and with DB table name
|
22 |
const DM_NORMAL_HOVERED_IMAGE = 5;
|
23 |
const DM_SELECTED_HOVERED_IMAGE = 6;
|
24 |
const DM_STATE_IMAGE = 7;
|
25 |
+
|
26 |
#endregion
|
27 |
|
28 |
+
public function loadByFilterPosition($object, $filterId, $position)
|
29 |
+
{
|
30 |
+
$read = $this->_getReadAdapter();
|
31 |
+
|
32 |
+
$select = $this->_getReadAdapter()->select()
|
33 |
+
->from($this->getMainTable())
|
34 |
+
->where($this->getMainTable() . '.' . 'filter_id' . '=?', $filterId)
|
35 |
+
->where($this->getMainTable() . '.' . 'position' . '=?', $position);
|
36 |
+
|
37 |
+
if ($read) {
|
38 |
+
$data = $read->fetchRow($select);
|
39 |
+
|
40 |
+
if ($data) {
|
41 |
+
$object->setData($data);
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
$this->unserializeFields($object);
|
46 |
+
$this->_afterLoad($object);
|
47 |
+
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
/**
|
52 |
* Invoked during resource model creation process, this method associates this resource model with model class
|
53 |
* and with DB table name
|
app/code/local/Mana/Filters/Resource/Filter2/Value/Store.php
CHANGED
@@ -122,7 +122,7 @@ class Mana_Filters_Resource_Filter2_Value_Store extends Mana_Filters_Resource_Fi
|
|
122 |
->joinLeft(array('store_option_value' => Mage::getSingleton('core/resource')->getTableName('eav/attribute_option_value')),
|
123 |
'store_option_value.option_id = eav_attribute_option.option_id AND store_option_value.store_id = core_store.store_id', null)
|
124 |
->joinLeft(array('target' => Mage::getSingleton('core/resource')->getTableName($this->getEntityName())),
|
125 |
-
'target.global_id = global.id AND target.store_id = core_store.store_id', null)
|
126 |
->distinct()
|
127 |
->where('core_store.store_id <> 0')
|
128 |
->where('global.edit_status = 0')
|
@@ -168,4 +168,8 @@ class Mana_Filters_Resource_Filter2_Value_Store extends Mana_Filters_Resource_Fi
|
|
168 |
$object->setName($values['name']);
|
169 |
$object->setPosition($values['position']);
|
170 |
}
|
|
|
|
|
|
|
|
|
171 |
}
|
122 |
->joinLeft(array('store_option_value' => Mage::getSingleton('core/resource')->getTableName('eav/attribute_option_value')),
|
123 |
'store_option_value.option_id = eav_attribute_option.option_id AND store_option_value.store_id = core_store.store_id', null)
|
124 |
->joinLeft(array('target' => Mage::getSingleton('core/resource')->getTableName($this->getEntityName())),
|
125 |
+
'target.global_id = global.id AND target.store_id = core_store.store_id', null)
|
126 |
->distinct()
|
127 |
->where('core_store.store_id <> 0')
|
128 |
->where('global.edit_status = 0')
|
168 |
$object->setName($values['name']);
|
169 |
$object->setPosition($values['position']);
|
170 |
}
|
171 |
+
|
172 |
+
public function loadByFilterPosition($object, $filterId, $position) {
|
173 |
+
throw new Exception('Not implemented');
|
174 |
+
}
|
175 |
}
|
app/code/local/Mana/Filters/Resource/Indexer/Source.php
CHANGED
@@ -11,6 +11,9 @@
|
|
11 |
*/
|
12 |
class Mana_Filters_Resource_Indexer_Source extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Eav_Source {
|
13 |
public function reindexEntities($processIds) {
|
|
|
|
|
|
|
14 |
$adapter = $this->_getWriteAdapter();
|
15 |
|
16 |
$this->clearTemporaryIndexTable();
|
11 |
*/
|
12 |
class Mana_Filters_Resource_Indexer_Source extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Eav_Source {
|
13 |
public function reindexEntities($processIds) {
|
14 |
+
// if (Mage::helper('mana_core')->isMageVersionEqualOrGreater('1.7')) {
|
15 |
+
// return parent::reindexEntities($processIds);
|
16 |
+
// }
|
17 |
$adapter = $this->_getWriteAdapter();
|
18 |
|
19 |
$this->clearTemporaryIndexTable();
|
app/code/local/Mana/Filters/Resource/Solr/And/Attribute.php
CHANGED
@@ -19,8 +19,6 @@ class Mana_Filters_Resource_Solr_And_Attribute extends Mana_Filters_Resource_Sol
|
|
19 |
*/
|
20 |
public function applyToCollection($collection, $model, $value)
|
21 |
{
|
22 |
-
$
|
23 |
-
$facetField = $engine->getSearchEngineFieldName($model->getAttributeModel(), 'nav');
|
24 |
-
$collection->addFqFilter(array($facetField => array('and' => $value)));
|
25 |
}
|
26 |
}
|
19 |
*/
|
20 |
public function applyToCollection($collection, $model, $value)
|
21 |
{
|
22 |
+
$collection->addFqFilter(array($model->getFilterField() => array('and' => $value)));
|
|
|
|
|
23 |
}
|
24 |
}
|
app/code/local/Mana/Filters/Resource/Solr/Attribute.php
CHANGED
@@ -13,14 +13,12 @@ class Mana_Filters_Resource_Solr_Attribute extends Mana_Filters_Resource_Filter_
|
|
13 |
{
|
14 |
/**
|
15 |
* @param Enterprise_Search_Model_Resource_Collection $collection
|
16 |
-
* @param
|
17 |
* @return Mana_Filters_Resource_Solr_Attribute
|
18 |
*/
|
19 |
public function countOnCollection($collection, $model)
|
20 |
{
|
21 |
-
$
|
22 |
-
$facetField = $engine->getSearchEngineFieldName($model->getAttributeModel(), 'nav');
|
23 |
-
$collection->setFacetCondition($facetField);
|
24 |
|
25 |
return $collection;
|
26 |
}
|
@@ -33,8 +31,6 @@ class Mana_Filters_Resource_Solr_Attribute extends Mana_Filters_Resource_Filter_
|
|
33 |
*/
|
34 |
public function applyToCollection($collection, $model, $value)
|
35 |
{
|
36 |
-
$
|
37 |
-
$facetField = $engine->getSearchEngineFieldName($model->getAttributeModel(), 'nav');
|
38 |
-
$collection->addFqFilter(array($facetField => array('or' => $value)));
|
39 |
}
|
40 |
}
|
13 |
{
|
14 |
/**
|
15 |
* @param Enterprise_Search_Model_Resource_Collection $collection
|
16 |
+
* @param Mana_Filters_Model_Solr_Attribute $model
|
17 |
* @return Mana_Filters_Resource_Solr_Attribute
|
18 |
*/
|
19 |
public function countOnCollection($collection, $model)
|
20 |
{
|
21 |
+
$collection->setFacetCondition($model->getFilterField());
|
|
|
|
|
22 |
|
23 |
return $collection;
|
24 |
}
|
31 |
*/
|
32 |
public function applyToCollection($collection, $model, $value)
|
33 |
{
|
34 |
+
$collection->addFqFilter(array($model->getFilterField() => array('or' => $value)));
|
|
|
|
|
35 |
}
|
36 |
}
|
app/code/local/Mana/Filters/Resource/Solr/Collection.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Filters
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Filters_Resource_Solr_Collection extends Enterprise_Search_Model_Resource_Collection {
|
13 |
+
/**
|
14 |
+
* Flag that defines if faceted data needs to be loaded
|
15 |
+
*
|
16 |
+
* @var bool
|
17 |
+
*/
|
18 |
+
protected $_facetedDataIsLoaded = false;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Load faceted data if not loaded
|
22 |
+
*
|
23 |
+
* @return Enterprise_Search_Model_Resource_Collection
|
24 |
+
*/
|
25 |
+
public function loadFacetedData($additionalParams = array()) {
|
26 |
+
if (empty($this->_facetedConditions)) {
|
27 |
+
$this->_facetedData = array();
|
28 |
+
|
29 |
+
return $this;
|
30 |
+
}
|
31 |
+
|
32 |
+
list($query, $params) = $this->_prepareBaseParams();
|
33 |
+
$params['solr_params']['facet'] = 'on';
|
34 |
+
$params['facet'] = $this->_facetedConditions;
|
35 |
+
$params = array_merge($params, $additionalParams);
|
36 |
+
|
37 |
+
$result = $this->_engine->getResultForRequest($query, $params);
|
38 |
+
$this->_facetedData = isset($result['faceted_data']) ? $result['faceted_data'] : $result['facets'];
|
39 |
+
$this->_facetedDataIsLoaded = true;
|
40 |
+
|
41 |
+
return $this;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Return field faceted data from faceted search result
|
46 |
+
*
|
47 |
+
* @param string $field
|
48 |
+
*
|
49 |
+
* @return array
|
50 |
+
*/
|
51 |
+
public function getFacetedData($field, $additionalParams = array()) {
|
52 |
+
if (!$this->_facetedDataIsLoaded) {
|
53 |
+
$this->loadFacetedData($additionalParams);
|
54 |
+
}
|
55 |
+
|
56 |
+
if (isset($this->_facetedData[$field])) {
|
57 |
+
return $this->_facetedData[$field];
|
58 |
+
}
|
59 |
+
|
60 |
+
return array();
|
61 |
+
}
|
62 |
+
}
|
app/code/local/Mana/Filters/Resource/Solr/Engine.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Filters
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/**
|
9 |
+
* @author Mana Team
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
class Mana_Filters_Resource_Solr_Engine extends Enterprise_Search_Model_Resource_Engine {
|
13 |
+
/**
|
14 |
+
* Retrieve results for search request
|
15 |
+
*
|
16 |
+
* @param string $query
|
17 |
+
* @param array $params
|
18 |
+
* @param string $entityType 'product'|'cms'
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
public function getResultForRequest($query, $params = array(), $entityType = 'product') {
|
22 |
+
return $this->_adapter->search($query, $params);
|
23 |
+
}
|
24 |
+
}
|
app/code/local/Mana/Filters/Resource/Solr/Reverse/Attribute.php
CHANGED
@@ -19,8 +19,6 @@ class Mana_Filters_Resource_Solr_Reverse_Attribute extends Mana_Filters_Resource
|
|
19 |
*/
|
20 |
public function applyToCollection($collection, $model, $value)
|
21 |
{
|
22 |
-
$
|
23 |
-
$facetField = $engine->getSearchEngineFieldName($model->getAttributeModel(), 'nav');
|
24 |
-
$collection->addFqFilter(array($facetField => array('reverse' => $value)));
|
25 |
}
|
26 |
}
|
19 |
*/
|
20 |
public function applyToCollection($collection, $model, $value)
|
21 |
{
|
22 |
+
$collection->addFqFilter(array($model->getFilterField() => array('reverse' => $value)));
|
|
|
|
|
23 |
}
|
24 |
}
|
app/code/local/Mana/Filters/etc/config.xml
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
<Mana_Filters>
|
13 |
<!-- This version number identifies version of database tables specific to this extension. It is written to
|
14 |
core_resource table. -->
|
15 |
-
<version>
|
16 |
</Mana_Filters>
|
17 |
</modules>
|
18 |
|
@@ -65,6 +65,12 @@
|
|
65 |
<adapter_phpExtension>Mana_Filters_Model_Solr_Adapter_PhpExtension</adapter_phpExtension>
|
66 |
</rewrite>
|
67 |
</enterprise_search>
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
<!-- BASED ON SNIPPET: Resources/Resource support (config.xml) -->
|
69 |
<!-- This says that string 'mana_filters' corresponds to Mana_Filters_Resource pseudo-namespace in
|
70 |
getResourceModel() calls. -->
|
@@ -135,6 +141,16 @@
|
|
135 |
</mana_filters>
|
136 |
</observers>
|
137 |
</prepare_catalog_product_index_select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
</events>
|
139 |
<!-- INSERT HERE: blocks, models, ... -->
|
140 |
</global>
|
@@ -221,7 +237,8 @@
|
|
221 |
<reverse_resource>mana_filters/filter_reverse_attribute</reverse_resource>
|
222 |
<template>mana/filters/items/list.phtml</template><!-- PHTML to be rendered -->
|
223 |
<sort_order>50</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
224 |
-
|
|
|
225 |
<standard translate="title" module="mana_filters">
|
226 |
<title>Text (One Item Can Be Selected At A Time)</title><!-- this one is displayed in admin -->
|
227 |
<block>mana_filters/filter</block>
|
@@ -234,7 +251,8 @@
|
|
234 |
<reverse_resource>mana_filters/filter_reverse_attribute</reverse_resource>
|
235 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
236 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
237 |
-
|
|
|
238 |
</attribute>
|
239 |
<price> <!-- available display options for price filter -->
|
240 |
<!-- by default, filter items are displayed as HTML list -->
|
@@ -248,7 +266,8 @@
|
|
248 |
<reverse_resource>mana_filters/filter_reverse_price</reverse_resource>
|
249 |
<template>mana/filters/items/list.phtml</template><!-- PHTML to be rendered -->
|
250 |
<sort_order>50</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
251 |
-
|
|
|
252 |
<standard translate="title" module="mana_filters">
|
253 |
<title>Text (One Item Can Be Selected At A Time)</title><!-- this one is displayed in admin -->
|
254 |
<block>mana_filters/filter</block>
|
@@ -259,7 +278,8 @@
|
|
259 |
<reverse_resource>mana_filters/filter_reverse_price</reverse_resource>
|
260 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
261 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
262 |
-
|
|
|
263 |
</price>
|
264 |
<category> <!-- available display options for category filter -->
|
265 |
<!-- by default, filter items are displayed as HTML list -->
|
@@ -270,7 +290,8 @@
|
|
270 |
<solr_model>mana_filters/solr_category</solr_model>
|
271 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
272 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
273 |
-
|
|
|
274 |
</category>
|
275 |
<decimal> <!-- available display options for decimal filters -->
|
276 |
<!-- by default, filter items are displayed as HTML list -->
|
@@ -284,7 +305,8 @@
|
|
284 |
<reverse_resource>mana_filters/filter_reverse_decimal</reverse_resource>
|
285 |
<template>mana/filters/items/list.phtml</template><!-- PHTML to be rendered -->
|
286 |
<sort_order>50</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
287 |
-
|
|
|
288 |
<standard translate="title" module="mana_filters">
|
289 |
<title>Text (One Item Can Be Selected At A Time)</title><!-- this one is displayed in admin -->
|
290 |
<block>mana_filters/filter</block>
|
@@ -295,7 +317,8 @@
|
|
295 |
<reverse_resource>mana_filters/filter_reverse_decimal</reverse_resource>
|
296 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
297 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
298 |
-
|
|
|
299 |
</decimal>
|
300 |
</display>
|
301 |
|
12 |
<Mana_Filters>
|
13 |
<!-- This version number identifies version of database tables specific to this extension. It is written to
|
14 |
core_resource table. -->
|
15 |
+
<version>13.10.14.16</version>
|
16 |
</Mana_Filters>
|
17 |
</modules>
|
18 |
|
65 |
<adapter_phpExtension>Mana_Filters_Model_Solr_Adapter_PhpExtension</adapter_phpExtension>
|
66 |
</rewrite>
|
67 |
</enterprise_search>
|
68 |
+
<enterprise_search_resource>
|
69 |
+
<rewrite>
|
70 |
+
<collection>Mana_Filters_Resource_Solr_Collection</collection>
|
71 |
+
<engine>Mana_Filters_Resource_Solr_Engine</engine>
|
72 |
+
</rewrite>
|
73 |
+
</enterprise_search_resource>
|
74 |
<!-- BASED ON SNIPPET: Resources/Resource support (config.xml) -->
|
75 |
<!-- This says that string 'mana_filters' corresponds to Mana_Filters_Resource pseudo-namespace in
|
76 |
getResourceModel() calls. -->
|
141 |
</mana_filters>
|
142 |
</observers>
|
143 |
</prepare_catalog_product_index_select>
|
144 |
+
<core_block_abstract_to_html_after><!-- this is event name this module listens for -->
|
145 |
+
<observers>
|
146 |
+
<mana_filters>
|
147 |
+
<class>mana_filters/observer</class>
|
148 |
+
<!-- model name of class containing event handler methods -->
|
149 |
+
<method>hideCmsContentOnFilteredPages</method>
|
150 |
+
<!-- event handler method name -->
|
151 |
+
</mana_filters>
|
152 |
+
</observers>
|
153 |
+
</core_block_abstract_to_html_after>
|
154 |
</events>
|
155 |
<!-- INSERT HERE: blocks, models, ... -->
|
156 |
</global>
|
237 |
<reverse_resource>mana_filters/filter_reverse_attribute</reverse_resource>
|
238 |
<template>mana/filters/items/list.phtml</template><!-- PHTML to be rendered -->
|
239 |
<sort_order>50</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
240 |
+
<popup_class>Mana/LayeredNavigation/Popup/List</popup_class>
|
241 |
+
</list>
|
242 |
<standard translate="title" module="mana_filters">
|
243 |
<title>Text (One Item Can Be Selected At A Time)</title><!-- this one is displayed in admin -->
|
244 |
<block>mana_filters/filter</block>
|
251 |
<reverse_resource>mana_filters/filter_reverse_attribute</reverse_resource>
|
252 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
253 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
254 |
+
<popup_class>Mana/LayeredNavigation/Popup/Standard</popup_class>
|
255 |
+
</standard>
|
256 |
</attribute>
|
257 |
<price> <!-- available display options for price filter -->
|
258 |
<!-- by default, filter items are displayed as HTML list -->
|
266 |
<reverse_resource>mana_filters/filter_reverse_price</reverse_resource>
|
267 |
<template>mana/filters/items/list.phtml</template><!-- PHTML to be rendered -->
|
268 |
<sort_order>50</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
269 |
+
<popup_class>Mana/LayeredNavigation/Popup/List</popup_class>
|
270 |
+
</list>
|
271 |
<standard translate="title" module="mana_filters">
|
272 |
<title>Text (One Item Can Be Selected At A Time)</title><!-- this one is displayed in admin -->
|
273 |
<block>mana_filters/filter</block>
|
278 |
<reverse_resource>mana_filters/filter_reverse_price</reverse_resource>
|
279 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
280 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
281 |
+
<popup_class>Mana/LayeredNavigation/Popup/Standard</popup_class>
|
282 |
+
</standard>
|
283 |
</price>
|
284 |
<category> <!-- available display options for category filter -->
|
285 |
<!-- by default, filter items are displayed as HTML list -->
|
290 |
<solr_model>mana_filters/solr_category</solr_model>
|
291 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
292 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
293 |
+
<popup_class>Mana/LayeredNavigation/Popup/Standard</popup_class>
|
294 |
+
</standard>
|
295 |
</category>
|
296 |
<decimal> <!-- available display options for decimal filters -->
|
297 |
<!-- by default, filter items are displayed as HTML list -->
|
305 |
<reverse_resource>mana_filters/filter_reverse_decimal</reverse_resource>
|
306 |
<template>mana/filters/items/list.phtml</template><!-- PHTML to be rendered -->
|
307 |
<sort_order>50</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
308 |
+
<popup_class>Mana/LayeredNavigation/Popup/List</popup_class>
|
309 |
+
</list>
|
310 |
<standard translate="title" module="mana_filters">
|
311 |
<title>Text (One Item Can Be Selected At A Time)</title><!-- this one is displayed in admin -->
|
312 |
<block>mana_filters/filter</block>
|
317 |
<reverse_resource>mana_filters/filter_reverse_decimal</reverse_resource>
|
318 |
<template>mana/filters/items/standard.phtml</template><!-- PHTML to be rendered -->
|
319 |
<sort_order>100</sort_order><!-- Position in "Display as" list. The item with least position is the default one. -->
|
320 |
+
<popup_class>Mana/LayeredNavigation/Popup/Standard</popup_class>
|
321 |
+
</standard>
|
322 |
</decimal>
|
323 |
</display>
|
324 |
|
app/code/local/Mana/Filters/sql/mana_filters_setup/mysql4-upgrade-13.09.11.14-13.09.23.17.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* BASED ON SNIPPET: Resources/Install/upgrade script */
|
4 |
+
if (defined('COMPILER_INCLUDE_PATH')) {
|
5 |
+
throw new Exception(Mage::helper('mana_core')->__('This Magento installation contains pending database installation/upgrade scripts. Please turn off Magento compilation feature while installing/upgrading new modules in Admin Panel menu System->Tools->Compilation.'));
|
6 |
+
}
|
7 |
+
|
8 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
9 |
+
$installer = $this;
|
10 |
+
if (method_exists($this->getConnection(), 'allowDdlCache')) {
|
11 |
+
$this->getConnection()->allowDdlCache();
|
12 |
+
}
|
13 |
+
|
14 |
+
foreach (array('mana_filters/filter2', 'mana_filters/filter2_store') as $table) {
|
15 |
+
$installer->run("
|
16 |
+
ALTER TABLE `{$this->getTable($table)}` ADD COLUMN (
|
17 |
+
`disable_no_result_options` tinyint NOT NULL default '1'
|
18 |
+
);
|
19 |
+
");
|
20 |
+
}
|
21 |
+
|
22 |
+
if (method_exists($this->getConnection(), 'disallowDdlCache')) {
|
23 |
+
$this->getConnection()->disallowDdlCache();
|
24 |
+
}
|
25 |
+
$installer->endSetup();
|
26 |
+
|
27 |
+
if (!Mage::registry('m_run_db_replication')) {
|
28 |
+
Mage::register('m_run_db_replication', true);
|
29 |
+
}
|
app/design/adminhtml/default/default/layout/mana_core.xml
CHANGED
@@ -26,8 +26,11 @@ examples on what kind of actions can be applied to referenced blocks.
|
|
26 |
</default>
|
27 |
<jquery_core>
|
28 |
<reference name="head">
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
31 |
<action method="addJs"><script>jquery/jquery.printf.js</script></action>
|
32 |
<action method="addJs"><script>mana/core.js</script></action>
|
33 |
<action method="addCss"><stylesheet>css/mana_core.css</stylesheet></action>
|
26 |
</default>
|
27 |
<jquery_core>
|
28 |
<reference name="head">
|
29 |
+
<!-- BEGIN: files which are managed in System->Configuration->MANAdev->General->JavaScript Libraries -->
|
30 |
+
<!--<action method="addJs"><script>jquery/require.js</script></action>-->
|
31 |
+
<action method="addJs"><script>jquery/jquery.js</script></action>
|
32 |
+
<!-- END: files which are managed in System->Configuration->MANAdev->General->JavaScript Libraries -->
|
33 |
+
|
34 |
<action method="addJs"><script>jquery/jquery.printf.js</script></action>
|
35 |
<action method="addJs"><script>mana/core.js</script></action>
|
36 |
<action method="addCss"><stylesheet>css/mana_core.css</stylesheet></action>
|
app/design/adminhtml/default/default/template/mana/core/js.phtml
CHANGED
@@ -6,6 +6,10 @@
|
|
6 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
*/
|
8 |
/* @var $this Mana_Core_Block_Js */
|
|
|
|
|
|
|
|
|
9 |
?>
|
10 |
<script type="text/javascript">
|
11 |
//<![CDATA[
|
@@ -17,5 +21,10 @@
|
|
17 |
$.options(<?php echo json_encode($_options) ?>);
|
18 |
<?php endif; ?>
|
19 |
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
20 |
//]]>
|
21 |
</script>
|
6 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
*/
|
8 |
/* @var $this Mana_Core_Block_Js */
|
9 |
+
|
10 |
+
/* @var $core Mana_Core_Helper_Data */
|
11 |
+
$core = Mage::helper('mana_core');
|
12 |
+
|
13 |
?>
|
14 |
<script type="text/javascript">
|
15 |
//<![CDATA[
|
21 |
$.options(<?php echo json_encode($_options) ?>);
|
22 |
<?php endif; ?>
|
23 |
})(jQuery);
|
24 |
+
<?php if ($_config = $this->getConfig()) : ?>
|
25 |
+
Mana.require(['singleton:Mana/Core/Config'], function(config) {
|
26 |
+
config.set(<?php echo $core->jsonForceObjectAndEncode($_config)?>);
|
27 |
+
});
|
28 |
+
<?php endif; ?>
|
29 |
//]]>
|
30 |
</script>
|
app/design/adminhtml/default/default/template/mana/core/require.phtml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/* @var $this Mana_Core_Block_Require */
|
9 |
+
?>
|
10 |
+
<script type="text/javascript">
|
11 |
+
var require = {
|
12 |
+
baseUrl: '<?php echo $this->getBaseRequireUrl() ?>'
|
13 |
+
};
|
14 |
+
</script>
|
app/design/frontend/base/default/layout/mana_core.xml
CHANGED
@@ -26,8 +26,11 @@ examples on what kind of actions can be applied to referenced blocks.
|
|
26 |
</default>
|
27 |
<jquery_core>
|
28 |
<reference name="head">
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
31 |
<action method="addJs"><script>jquery/jquery.printf.js</script></action>
|
32 |
<action method="addJs"><script>mana/core.js</script></action>
|
33 |
<action method="addCss"><stylesheet>css/mana_core.css</stylesheet></action>
|
26 |
</default>
|
27 |
<jquery_core>
|
28 |
<reference name="head">
|
29 |
+
<!-- BEGIN: files which are managed in System->Configuration->MANAdev->General->JavaScript Libraries -->
|
30 |
+
<!--<action method="addJs"><script>jquery/require.js</script></action>-->
|
31 |
+
<action method="addJs"><script>jquery/jquery.js</script></action>
|
32 |
+
<!-- END: files which are managed in System->Configuration->MANAdev->General->JavaScript Libraries -->
|
33 |
+
|
34 |
<action method="addJs"><script>jquery/jquery.printf.js</script></action>
|
35 |
<action method="addJs"><script>mana/core.js</script></action>
|
36 |
<action method="addCss"><stylesheet>css/mana_core.css</stylesheet></action>
|
app/design/frontend/base/default/template/mana/core/js.phtml
CHANGED
@@ -6,6 +6,10 @@
|
|
6 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
*/
|
8 |
/* @var $this Mana_Core_Block_Js */
|
|
|
|
|
|
|
|
|
9 |
?>
|
10 |
<script type="text/javascript">
|
11 |
//<![CDATA[
|
@@ -16,6 +20,11 @@
|
|
16 |
<?php if ($_options = $this->getOptions()) : ?>
|
17 |
$.options(<?php echo json_encode($_options) ?>);
|
18 |
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
19 |
})(jQuery);
|
20 |
//]]>
|
21 |
</script>
|
6 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
*/
|
8 |
/* @var $this Mana_Core_Block_Js */
|
9 |
+
|
10 |
+
/* @var $core Mana_Core_Helper_Data */
|
11 |
+
$core = Mage::helper('mana_core');
|
12 |
+
|
13 |
?>
|
14 |
<script type="text/javascript">
|
15 |
//<![CDATA[
|
20 |
<?php if ($_options = $this->getOptions()) : ?>
|
21 |
$.options(<?php echo json_encode($_options) ?>);
|
22 |
<?php endif; ?>
|
23 |
+
<?php if ($_config = $this->getConfig()) : ?>
|
24 |
+
Mana.require(['singleton:Mana/Core/Config'], function (config) {
|
25 |
+
config.set(<?php echo $core->jsonForceObjectAndEncode($_config)?>);
|
26 |
+
});
|
27 |
+
<?php endif; ?>
|
28 |
})(jQuery);
|
29 |
//]]>
|
30 |
</script>
|
app/design/frontend/base/default/template/mana/core/require.phtml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category Mana
|
4 |
+
* @package Mana_Core
|
5 |
+
* @copyright Copyright (c) http://www.manadev.com
|
6 |
+
* @license http://www.manadev.com/license Proprietary License
|
7 |
+
*/
|
8 |
+
/* @var $this Mana_Core_Block_Require */
|
9 |
+
?>
|
10 |
+
<script type="text/javascript">
|
11 |
+
var require = {
|
12 |
+
baseUrl: '<?php echo $this->getBaseRequireUrl() ?>'
|
13 |
+
};
|
14 |
+
</script>
|
app/design/frontend/base/default/template/mana/filters/cms.phtml
CHANGED
@@ -5,5 +5,25 @@
|
|
5 |
* @copyright Copyright (c) http://www.manadev.com
|
6 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
?>
|
9 |
-
<?php
|
|
|
|
|
|
|
|
5 |
* @copyright Copyright (c) http://www.manadev.com
|
6 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
*/
|
8 |
+
|
9 |
+
/* @var $this Mage_Core_Block_Template */
|
10 |
+
|
11 |
+
/* @var $_core Mana_Core_Helper_Data */
|
12 |
+
$_core = Mage::helper('mana_core');
|
13 |
+
|
14 |
+
/* @var $core Mana_Filters_Helper_Data */
|
15 |
+
$_filters = Mage::helper('mana_filters');
|
16 |
+
|
17 |
+
$_hideWhenNoFiltersApplied =
|
18 |
+
($this->hasData('hide_when_no_filters_applied')
|
19 |
+
? $this->getData('hide_when_no_filters_applied')
|
20 |
+
: Mage::getStoreConfigFlag('mana_filters/display/hide_cms_product_list'));
|
21 |
+
$_isFilterApplied = ($state = $_filters->getLayer()->getState()) && $state->getFilters();
|
22 |
+
$_isProductListVisible = $_isFilterApplied || !$_hideWhenNoFiltersApplied;
|
23 |
+
|
24 |
?>
|
25 |
+
<?php if ($_isProductListVisible) : ?>
|
26 |
+
<?php echo $this->getChildHtml('product_list') ?>
|
27 |
+
<?php else: ?>
|
28 |
+
<?php echo $_core->getEmptyBlockHtml($this->getChild('product_list')) ?>
|
29 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/mana/filters/items/list.phtml
CHANGED
@@ -19,11 +19,11 @@
|
|
19 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
20 |
<?php // MANA BEGIN ?>
|
21 |
<?php if ($_item->getMSelected()): ?>
|
22 |
-
<span class="m-selected-filter-item"><?php echo $_item->getLabel() ?></span>
|
23 |
<?php else : ?>
|
24 |
-
<?php if ($_item->getCount() > 0): ?>
|
25 |
-
<a href="<?php echo $this->urlEscape($_item->getUrl()) ?>" title="<?php echo $_item->getLabel() ?>"><?php echo $_item->getLabel() ?></a>
|
26 |
-
<?php else: echo $_item->getLabel() ?>
|
27 |
<?php endif; ?>
|
28 |
<?php endif; ?>
|
29 |
<?php // MANA END ?>
|
19 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
20 |
<?php // MANA BEGIN ?>
|
21 |
<?php if ($_item->getMSelected()): ?>
|
22 |
+
<span class="m-selected-filter-item"><?php echo $this->escapeHtml($_item->getLabel()) ?></span>
|
23 |
<?php else : ?>
|
24 |
+
<?php if (!$this->getFilterOptions()->getDisableNoResultOptions() || $_item->getCount() > 0 || $_item->getMSelected()): ?>
|
25 |
+
<a href="<?php echo $this->urlEscape($_item->getUrl()) ?>" title="<?php echo $this->escapeHtml($_item->getLabel()) ?>"><?php echo $this->escapeHtml($_item->getLabel()) ?></a>
|
26 |
+
<?php else: echo $this->escapeHtml($_item->getLabel()) ?>
|
27 |
<?php endif; ?>
|
28 |
<?php endif; ?>
|
29 |
<?php // MANA END ?>
|
app/design/frontend/base/default/template/mana/filters/items/list_popup.phtml
CHANGED
@@ -11,6 +11,8 @@
|
|
11 |
/* @var $this Mana_Filters_Block_Filter_Attribute */
|
12 |
/* @var $filters Mana_Filters_Helper_Data */ $filters = Mage::helper(strtolower('Mana_Filters'));
|
13 |
/* @var $showmore ManaPro_FilterShowMore_Helper_Data */ $showmore = Mage::helper(strtolower('ManaPro_FilterShowMore'));
|
|
|
|
|
14 |
$MAX_ROW_COUNT = $showmore->getMaxRowCount(); // 20
|
15 |
$MAX_COLUMN_COUNT = $showmore->getMaxColumnCount(); // 4
|
16 |
$items = $this->getItems();
|
@@ -25,11 +27,13 @@ list($rowCount, $columnCount) = $showmore->getPopupDimensions($items, $MAX_ROW_C
|
|
25 |
<?php $_item = $items[$columnIndex * $rowCount + $rowIndex]; ?>
|
26 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
27 |
<?php //if ($_item->getCount() > 0): ?>
|
28 |
-
<a href="#" title="<?php echo $_item->getLabel() ?>"
|
29 |
-
|
30 |
-
|
|
|
|
|
31 |
</a>
|
32 |
-
<?php //else: echo $_item->getLabel(); ?>
|
33 |
<?php //endif; ?>
|
34 |
<?php if (Mage::getStoreConfigFlag('mana_filters/display/count')) : ?>
|
35 |
(<?php echo $_item->getCount() ?>)
|
@@ -41,11 +45,9 @@ list($rowCount, $columnCount) = $showmore->getPopupDimensions($items, $MAX_ROW_C
|
|
41 |
<?php endfor; ?>
|
42 |
</ol>
|
43 |
<div class="buttons-set">
|
44 |
-
<button type="button" title="<?php echo $this->__('Close') ?>" class="button"
|
45 |
-
onclick="return jQuery.mClosePopup();">
|
46 |
<span><span><?php echo $this->__('Close') ?></span></span></button>
|
47 |
-
<button type="button" title="<?php echo $this->__('Apply') ?>" class="button"
|
48 |
-
onclick="return jQuery.mShowMorePopupApply();">
|
49 |
<span><span><?php echo $this->__('Apply') ?></span></span></button>
|
50 |
</div>
|
51 |
</div>
|
11 |
/* @var $this Mana_Filters_Block_Filter_Attribute */
|
12 |
/* @var $filters Mana_Filters_Helper_Data */ $filters = Mage::helper(strtolower('Mana_Filters'));
|
13 |
/* @var $showmore ManaPro_FilterShowMore_Helper_Data */ $showmore = Mage::helper(strtolower('ManaPro_FilterShowMore'));
|
14 |
+
/* @var $jsonHelper Mana_Core_Helper_Json */
|
15 |
+
$jsonHelper = Mage::helper('mana_core/json');
|
16 |
$MAX_ROW_COUNT = $showmore->getMaxRowCount(); // 20
|
17 |
$MAX_COLUMN_COUNT = $showmore->getMaxColumnCount(); // 4
|
18 |
$items = $this->getItems();
|
27 |
<?php $_item = $items[$columnIndex * $rowCount + $rowIndex]; ?>
|
28 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
29 |
<?php //if ($_item->getCount() > 0): ?>
|
30 |
+
<a href="#" title="<?php echo $this->escapeHtml($_item->getLabel()) ?>"
|
31 |
+
data-item="<?php echo $jsonHelper->encodeAttribute($_item->getSeoData()) ?>"
|
32 |
+
data-is-reverse="<?php echo $this->getFilterOptions()->getIsReverse() ?>"
|
33 |
+
data-index="<?php echo $columnIndex * $rowCount + $rowIndex ?>">
|
34 |
+
<span <?php if ($_item->getMShowSelected()): ?>class="m-selected-filter-item"<?php endif; ?> ><?php echo $this->escapeHtml($_item->getLabel()) ?></span>
|
35 |
</a>
|
36 |
+
<?php //else: echo $this->escapeHtml($_item->getLabel()); ?>
|
37 |
<?php //endif; ?>
|
38 |
<?php if (Mage::getStoreConfigFlag('mana_filters/display/count')) : ?>
|
39 |
(<?php echo $_item->getCount() ?>)
|
45 |
<?php endfor; ?>
|
46 |
</ol>
|
47 |
<div class="buttons-set">
|
48 |
+
<button type="button" title="<?php echo $this->__('Close') ?>" class="button m-close">
|
|
|
49 |
<span><span><?php echo $this->__('Close') ?></span></span></button>
|
50 |
+
<button type="button" title="<?php echo $this->__('Apply') ?>" class="button m-apply">
|
|
|
51 |
<span><span><?php echo $this->__('Apply') ?></span></span></button>
|
52 |
</div>
|
53 |
</div>
|
app/design/frontend/base/default/template/mana/filters/items/standard.phtml
CHANGED
@@ -19,11 +19,11 @@
|
|
19 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
20 |
<?php // MANA BEGIN ?>
|
21 |
<?php if ($_item->getMSelected()): ?>
|
22 |
-
<span class="m-selected-filter-item"><?php echo $_item->getLabel() ?></span>
|
23 |
<?php else : ?>
|
24 |
-
<?php if ($_item->getCount() > 0): ?>
|
25 |
-
<a href="<?php echo $this->urlEscape($_item->getReplaceUrl()) ?>" title="<?php echo $_item->getLabel() ?>"><?php echo $_item->getLabel() ?></a>
|
26 |
-
<?php else: echo $_item->getLabel() ?>
|
27 |
<?php endif; ?>
|
28 |
<?php endif; ?>
|
29 |
<?php // MANA END ?>
|
19 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
20 |
<?php // MANA BEGIN ?>
|
21 |
<?php if ($_item->getMSelected()): ?>
|
22 |
+
<span class="m-selected-filter-item"><?php echo $this->escapeHtml($_item->getLabel()) ?></span>
|
23 |
<?php else : ?>
|
24 |
+
<?php if (!$this->getFilterOptions()->getDisableNoResultOptions() || $_item->getCount() > 0 || $_item->getMSelected()): ?>
|
25 |
+
<a href="<?php echo $this->urlEscape($_item->getReplaceUrl()) ?>" title="<?php echo $this->escapeHtml($_item->getLabel()) ?>"><?php echo $this->escapeHtml($_item->getLabel()) ?></a>
|
26 |
+
<?php else: echo $this->escapeHtml($_item->getLabel()) ?>
|
27 |
<?php endif; ?>
|
28 |
<?php endif; ?>
|
29 |
<?php // MANA END ?>
|
app/design/frontend/base/default/template/mana/filters/items/standard_popup.phtml
CHANGED
@@ -11,6 +11,8 @@
|
|
11 |
/* @var $this Mana_Filters_Block_Filter_Attribute */
|
12 |
/* @var $filters Mana_Filters_Helper_Data */ $filters = Mage::helper(strtolower('Mana_Filters'));
|
13 |
/* @var $showmore ManaPro_FilterShowMore_Helper_Data */ $showmore = Mage::helper(strtolower('ManaPro_FilterShowMore'));
|
|
|
|
|
14 |
$MAX_ROW_COUNT = $showmore->getMaxRowCount(); // 20
|
15 |
$MAX_COLUMN_COUNT = $showmore->getMaxColumnCount(); // 4
|
16 |
$items = $this->getItems();
|
@@ -25,12 +27,15 @@ list($rowCount, $columnCount) = $showmore->getPopupDimensions($items, $MAX_ROW_C
|
|
25 |
<?php $_item = $items[$columnIndex * $rowCount + $rowIndex]; ?>
|
26 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
27 |
<?php if ($_item->getMSelected()): ?>
|
28 |
-
<span class="m-selected-filter-item"><?php echo $_item->getLabel() ?></span>
|
29 |
<?php else : ?>
|
30 |
-
<?php if ($_item->getCount() > 0): ?>
|
31 |
-
<a href="#"
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
34 |
<?php endif; ?>
|
35 |
<?php endif; ?>
|
36 |
<?php if (Mage::getStoreConfigFlag('mana_filters/display/count')) : ?>
|
11 |
/* @var $this Mana_Filters_Block_Filter_Attribute */
|
12 |
/* @var $filters Mana_Filters_Helper_Data */ $filters = Mage::helper(strtolower('Mana_Filters'));
|
13 |
/* @var $showmore ManaPro_FilterShowMore_Helper_Data */ $showmore = Mage::helper(strtolower('ManaPro_FilterShowMore'));
|
14 |
+
/* @var $jsonHelper Mana_Core_Helper_Json */
|
15 |
+
$jsonHelper = Mage::helper('mana_core/json');
|
16 |
$MAX_ROW_COUNT = $showmore->getMaxRowCount(); // 20
|
17 |
$MAX_COLUMN_COUNT = $showmore->getMaxColumnCount(); // 4
|
18 |
$items = $this->getItems();
|
27 |
<?php $_item = $items[$columnIndex * $rowCount + $rowIndex]; ?>
|
28 |
<li <?php if ($_item->getMShowSelected()): ?>class="m-selected-ln-item"<?php endif; ?>>
|
29 |
<?php if ($_item->getMSelected()): ?>
|
30 |
+
<span class="m-selected-filter-item"><?php echo $this->escapeHtml($_item->getLabel()) ?></span>
|
31 |
<?php else : ?>
|
32 |
+
<?php if (!$this->getFilterOptions()->getDisableNoResultOptions() || $_item->getCount() > 0 || $_item->getMSelected()): ?>
|
33 |
+
<a href="#" title="<?php echo $this->escapeHtml($_item->getLabel()) ?>"
|
34 |
+
data-item="<?php echo $jsonHelper->encodeAttribute($_item->getSeoData()) ?>"
|
35 |
+
data-is-reverse="<?php echo $this->getFilterOptions()->getIsReverse() ?>"
|
36 |
+
data-index="<?php echo $columnIndex * $rowCount + $rowIndex ?>">
|
37 |
+
<?php echo $this->escapeHtml($_item->getLabel()) ?></a>
|
38 |
+
<?php else: echo $this->escapeHtml($_item->getLabel()) ?>
|
39 |
<?php endif; ?>
|
40 |
<?php endif; ?>
|
41 |
<?php if (Mage::getStoreConfigFlag('mana_filters/display/count')) : ?>
|
app/design/frontend/base/default/template/mana/filters/state.phtml
CHANGED
@@ -12,6 +12,7 @@
|
|
12 |
*
|
13 |
* @see Mage_Catalog_Block_Layer_State
|
14 |
*/
|
|
|
15 |
?>
|
16 |
<?php $_filters = $this->getActiveFilters() ?>
|
17 |
<?php if(!empty($_filters)): ?>
|
12 |
*
|
13 |
* @see Mage_Catalog_Block_Layer_State
|
14 |
*/
|
15 |
+
/* @var $this Mage_Catalog_Block_Layer_State */
|
16 |
?>
|
17 |
<?php $_filters = $this->getActiveFilters() ?>
|
18 |
<?php if(!empty($_filters)): ?>
|
app/etc/modules/Mana_Core.xml
CHANGED
@@ -15,6 +15,12 @@
|
|
15 |
<active>true</active>
|
16 |
<!-- This instructs Magento to search for module code in app/code/local directory. -->
|
17 |
<codePool>local</codePool>
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
<!-- INSERT HERE: depends -->
|
19 |
</Mana_Core>
|
20 |
</modules>
|
15 |
<active>true</active>
|
16 |
<!-- This instructs Magento to search for module code in app/code/local directory. -->
|
17 |
<codePool>local</codePool>
|
18 |
+
|
19 |
+
<Enterprise_PageCache>
|
20 |
+
<depends>
|
21 |
+
<Mana_Core />
|
22 |
+
</depends>
|
23 |
+
</Enterprise_PageCache>
|
24 |
<!-- INSERT HERE: depends -->
|
25 |
</Mana_Core>
|
26 |
</modules>
|
app/locale/en_US/Mana_Core.csv
CHANGED
@@ -17,3 +17,19 @@
|
|
17 |
"Configure Mana Extensions","Configure Mana Extensions"
|
18 |
"Please wait...","Please wait..."
|
19 |
"Loading...","Loading..."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
"Configure Mana Extensions","Configure Mana Extensions"
|
18 |
"Please wait...","Please wait..."
|
19 |
"Loading...","Loading..."
|
20 |
+
"General","General"
|
21 |
+
"MANAdev General Settings","MANAdev General Settings"
|
22 |
+
"JavaScript Libraries","JavaScript Libraries"
|
23 |
+
|
24 |
+
"jQuery (version 1.8.3)","jQuery (version 1.8.3)"
|
25 |
+
|
26 |
+
"Always runs in jQuery.noConflict() mode (slight modification) to prevent conflicts with Prototype JavaScript library used by Magento.","Always runs in jQuery.noConflict() mode (slight modification) to prevent conflicts with Prototype JavaScript library used by Magento."
|
27 |
+
"Load if required, minified version (recommended)","Load if required, minified version (recommended)"
|
28 |
+
"Load on all pages, minified version","Load on all pages, minified version"
|
29 |
+
"Load if required, full version with comments","Load if required, full version with comments"
|
30 |
+
"Load on all pages, full version with comments","Load on all pages, full version with comments"
|
31 |
+
"Do not load","Do not load"
|
32 |
+
"Take action as defined in theme layout XML files","Take action as defined in theme layout XML files"
|
33 |
+
"Use Default","Use Default"
|
34 |
+
"Advices, Warnings and Messages","Advices, Warnings and Messages"
|
35 |
+
"Global Configuration","Global Configuration"
|
app/locale/en_US/Mana_Db.csv
CHANGED
@@ -9,6 +9,18 @@
|
|
9 |
"Altering database keys currently not supported","Altering database keys currently not supported"
|
10 |
"%s/%s/%s: %s parameter is required","%s/%s/%s: %s parameter is required"
|
11 |
"Entities with circular dependencies found: %s","Entities with circular dependencies found: %s"
|
12 |
-
"Default Values","Default Values"
|
13 |
"Propagate default values throughout the system","Propagate default values throughout the system"
|
14 |
"Use Default","Use Default"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
"Altering database keys currently not supported","Altering database keys currently not supported"
|
10 |
"%s/%s/%s: %s parameter is required","%s/%s/%s: %s parameter is required"
|
11 |
"Entities with circular dependencies found: %s","Entities with circular dependencies found: %s"
|
12 |
+
"Default Values (MANAdev)","Default Values (MANAdev)"
|
13 |
"Propagate default values throughout the system","Propagate default values throughout the system"
|
14 |
"Use Default","Use Default"
|
15 |
+
"Setup version %s not found","Setup version %s not found"
|
16 |
+
"Entity Flat Data (MANAdev)","Entity Flat Data (MANAdev)"
|
17 |
+
"Reorganizes entity data to flat structure","Reorganizes entity data to flat structure"
|
18 |
+
"",""
|
19 |
+
"",""
|
20 |
+
"",""
|
21 |
+
"",""
|
22 |
+
"",""
|
23 |
+
"",""
|
24 |
+
"",""
|
25 |
+
"",""
|
26 |
+
"",""
|
app/locale/en_US/Mana_Filters.csv
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
"Can Store Customer Select Multiple Values","Can Store Customer Select Multiple Values"
|
11 |
"Code","Code"
|
12 |
"Name","Name"
|
13 |
-
"Use
|
14 |
"Display Filter Items As","Display Filter Items As"
|
15 |
"Position (selected at the top)","Position (selected at the top)"
|
16 |
"Name","Name"
|
@@ -21,4 +21,6 @@
|
|
21 |
"Logical AND","Logical AND"
|
22 |
"Reverse Mode","Reverse Mode"
|
23 |
"If enabled, shows all items as selected and lets user to deselect items he/she is not interested in","If enabled, shows all items as selected and lets user to deselect items he/she is not interested in"
|
24 |
-
"not","not"
|
|
|
|
10 |
"Can Store Customer Select Multiple Values","Can Store Customer Select Multiple Values"
|
11 |
"Code","Code"
|
12 |
"Name","Name"
|
13 |
+
"Use Attribute Configuration","Use Attribute Configuration"
|
14 |
"Display Filter Items As","Display Filter Items As"
|
15 |
"Position (selected at the top)","Position (selected at the top)"
|
16 |
"Name","Name"
|
21 |
"Logical AND","Logical AND"
|
22 |
"Reverse Mode","Reverse Mode"
|
23 |
"If enabled, shows all items as selected and lets user to deselect items he/she is not interested in","If enabled, shows all items as selected and lets user to deselect items he/she is not interested in"
|
24 |
+
"not","not"
|
25 |
+
"Layered Navigation (MANAdev)","Layered Navigation (MANAdev)"
|
26 |
+
"Recalculates formula-based layered navigation settings","Recalculates formula-based layered navigation settings"
|
js/jquery/froogaloop.js
ADDED
@@ -0,0 +1,290 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
; // for better merging
|
2 |
+
|
3 |
+
// Init style shamelessly stolen from jQuery http://jquery.com
|
4 |
+
var Froogaloop = (function(){
|
5 |
+
// Define a local copy of Froogaloop
|
6 |
+
function Froogaloop(iframe) {
|
7 |
+
// The Froogaloop object is actually just the init constructor
|
8 |
+
return new Froogaloop.fn.init(iframe);
|
9 |
+
}
|
10 |
+
|
11 |
+
var eventCallbacks = {},
|
12 |
+
hasWindowEvent = false,
|
13 |
+
isReady = false,
|
14 |
+
slice = Array.prototype.slice,
|
15 |
+
playerDomain = '';
|
16 |
+
|
17 |
+
Froogaloop.fn = Froogaloop.prototype = {
|
18 |
+
element: null,
|
19 |
+
|
20 |
+
init: function(iframe) {
|
21 |
+
if (typeof iframe === "string") {
|
22 |
+
iframe = document.getElementById(iframe);
|
23 |
+
}
|
24 |
+
|
25 |
+
this.element = iframe;
|
26 |
+
|
27 |
+
// Register message event listeners
|
28 |
+
playerDomain = getDomainFromUrl(this.element.getAttribute('src'));
|
29 |
+
|
30 |
+
return this;
|
31 |
+
},
|
32 |
+
|
33 |
+
/*
|
34 |
+
* Calls a function to act upon the player.
|
35 |
+
*
|
36 |
+
* @param {string} method The name of the Javascript API method to call. Eg: 'play'.
|
37 |
+
* @param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
|
38 |
+
* or callback function when the method returns a value.
|
39 |
+
*/
|
40 |
+
api: function(method, valueOrCallback) {
|
41 |
+
if (!this.element || !method) {
|
42 |
+
return false;
|
43 |
+
}
|
44 |
+
|
45 |
+
var self = this,
|
46 |
+
element = self.element,
|
47 |
+
target_id = element.id !== '' ? element.id : null,
|
48 |
+
params = !isFunction(valueOrCallback) ? valueOrCallback : null,
|
49 |
+
callback = isFunction(valueOrCallback) ? valueOrCallback : null;
|
50 |
+
|
51 |
+
// Store the callback for get functions
|
52 |
+
if (callback) {
|
53 |
+
storeCallback(method, callback, target_id);
|
54 |
+
}
|
55 |
+
|
56 |
+
postMessage(method, params, element);
|
57 |
+
return self;
|
58 |
+
},
|
59 |
+
|
60 |
+
/*
|
61 |
+
* Registers an event listener and a callback function that gets called when the event fires.
|
62 |
+
*
|
63 |
+
* @param eventName (String): Name of the event to listen for.
|
64 |
+
* @param callback (Function): Function that should be called when the event fires.
|
65 |
+
*/
|
66 |
+
addEvent: function(eventName, callback) {
|
67 |
+
if (!this.element) {
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
|
71 |
+
var self = this,
|
72 |
+
element = self.element,
|
73 |
+
target_id = element.id !== '' ? element.id : null;
|
74 |
+
|
75 |
+
|
76 |
+
storeCallback(eventName, callback, target_id);
|
77 |
+
|
78 |
+
// The ready event is not registered via postMessage. It fires regardless.
|
79 |
+
if (eventName != 'ready') {
|
80 |
+
postMessage('addEventListener', eventName, element);
|
81 |
+
}
|
82 |
+
else if (eventName == 'ready' && isReady) {
|
83 |
+
callback.call(null, target_id);
|
84 |
+
}
|
85 |
+
|
86 |
+
return self;
|
87 |
+
},
|
88 |
+
|
89 |
+
/*
|
90 |
+
* Unregisters an event listener that gets called when the event fires.
|
91 |
+
*
|
92 |
+
* @param eventName (String): Name of the event to stop listening for.
|
93 |
+
*/
|
94 |
+
removeEvent: function(eventName) {
|
95 |
+
if (!this.element) {
|
96 |
+
return false;
|
97 |
+
}
|
98 |
+
|
99 |
+
var self = this,
|
100 |
+
element = self.element,
|
101 |
+
target_id = element.id !== '' ? element.id : null,
|
102 |
+
removed = removeCallback(eventName, target_id);
|
103 |
+
|
104 |
+
// The ready event is not registered
|
105 |
+
if (eventName != 'ready' && removed) {
|
106 |
+
postMessage('removeEventListener', eventName, element);
|
107 |
+
}
|
108 |
+
}
|
109 |
+
};
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Handles posting a message to the parent window.
|
113 |
+
*
|
114 |
+
* @param method (String): name of the method to call inside the player. For api calls
|
115 |
+
* this is the name of the api method (api_play or api_pause) while for events this method
|
116 |
+
* is api_addEventListener.
|
117 |
+
* @param params (Object or Array): List of parameters to submit to the method. Can be either
|
118 |
+
* a single param or an array list of parameters.
|
119 |
+
* @param target (HTMLElement): Target iframe to post the message to.
|
120 |
+
*/
|
121 |
+
function postMessage(method, params, target) {
|
122 |
+
if (!target.contentWindow.postMessage) {
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
|
126 |
+
var url = target.getAttribute('src').split('?')[0],
|
127 |
+
data = JSON.stringify({
|
128 |
+
method: method,
|
129 |
+
value: params
|
130 |
+
});
|
131 |
+
|
132 |
+
if (url.substr(0, 2) === '//') {
|
133 |
+
url = window.location.protocol + url;
|
134 |
+
}
|
135 |
+
|
136 |
+
target.contentWindow.postMessage(data, url);
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Event that fires whenever the window receives a message from its parent
|
141 |
+
* via window.postMessage.
|
142 |
+
*/
|
143 |
+
function onMessageReceived(event) {
|
144 |
+
var data, method;
|
145 |
+
|
146 |
+
try {
|
147 |
+
data = JSON.parse(event.data);
|
148 |
+
method = data.event || data.method;
|
149 |
+
}
|
150 |
+
catch(e) {
|
151 |
+
//fail silently... like a ninja!
|
152 |
+
}
|
153 |
+
|
154 |
+
if (method == 'ready' && !isReady) {
|
155 |
+
isReady = true;
|
156 |
+
}
|
157 |
+
|
158 |
+
// Handles messages from moogaloop only
|
159 |
+
if (event.origin != playerDomain) {
|
160 |
+
return false;
|
161 |
+
}
|
162 |
+
|
163 |
+
var value = data.value,
|
164 |
+
eventData = data.data,
|
165 |
+
target_id = target_id === '' ? null : data.player_id,
|
166 |
+
|
167 |
+
callback = getCallback(method, target_id),
|
168 |
+
params = [];
|
169 |
+
|
170 |
+
if (!callback) {
|
171 |
+
return false;
|
172 |
+
}
|
173 |
+
|
174 |
+
if (value !== undefined) {
|
175 |
+
params.push(value);
|
176 |
+
}
|
177 |
+
|
178 |
+
if (eventData) {
|
179 |
+
params.push(eventData);
|
180 |
+
}
|
181 |
+
|
182 |
+
if (target_id) {
|
183 |
+
params.push(target_id);
|
184 |
+
}
|
185 |
+
|
186 |
+
return params.length > 0 ? callback.apply(null, params) : callback.call();
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Stores submitted callbacks for each iframe being tracked and each
|
192 |
+
* event for that iframe.
|
193 |
+
*
|
194 |
+
* @param eventName (String): Name of the event. Eg. api_onPlay
|
195 |
+
* @param callback (Function): Function that should get executed when the
|
196 |
+
* event is fired.
|
197 |
+
* @param target_id (String) [Optional]: If handling more than one iframe then
|
198 |
+
* it stores the different callbacks for different iframes based on the iframe's
|
199 |
+
* id.
|
200 |
+
*/
|
201 |
+
function storeCallback(eventName, callback, target_id) {
|
202 |
+
if (target_id) {
|
203 |
+
if (!eventCallbacks[target_id]) {
|
204 |
+
eventCallbacks[target_id] = {};
|
205 |
+
}
|
206 |
+
eventCallbacks[target_id][eventName] = callback;
|
207 |
+
}
|
208 |
+
else {
|
209 |
+
eventCallbacks[eventName] = callback;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Retrieves stored callbacks.
|
215 |
+
*/
|
216 |
+
function getCallback(eventName, target_id) {
|
217 |
+
if (target_id) {
|
218 |
+
return eventCallbacks[target_id][eventName];
|
219 |
+
}
|
220 |
+
else {
|
221 |
+
return eventCallbacks[eventName];
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
+
function removeCallback(eventName, target_id) {
|
226 |
+
if (target_id && eventCallbacks[target_id]) {
|
227 |
+
if (!eventCallbacks[target_id][eventName]) {
|
228 |
+
return false;
|
229 |
+
}
|
230 |
+
eventCallbacks[target_id][eventName] = null;
|
231 |
+
}
|
232 |
+
else {
|
233 |
+
if (!eventCallbacks[eventName]) {
|
234 |
+
return false;
|
235 |
+
}
|
236 |
+
eventCallbacks[eventName] = null;
|
237 |
+
}
|
238 |
+
|
239 |
+
return true;
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Returns a domain's root domain.
|
244 |
+
* Eg. returns http://vimeo.com when http://vimeo.com/channels is sbumitted
|
245 |
+
*
|
246 |
+
* @param url (String): Url to test against.
|
247 |
+
* @return url (String): Root domain of submitted url
|
248 |
+
*/
|
249 |
+
function getDomainFromUrl(url) {
|
250 |
+
if (url.substr(0, 2) === '//') {
|
251 |
+
url = window.location.protocol + url;
|
252 |
+
}
|
253 |
+
|
254 |
+
var url_pieces = url.split('/'),
|
255 |
+
domain_str = '';
|
256 |
+
|
257 |
+
for(var i = 0, length = url_pieces.length; i < length; i++) {
|
258 |
+
if(i<3) {domain_str += url_pieces[i];}
|
259 |
+
else {break;}
|
260 |
+
if(i<2) {domain_str += '/';}
|
261 |
+
}
|
262 |
+
|
263 |
+
return domain_str;
|
264 |
+
}
|
265 |
+
|
266 |
+
function isFunction(obj) {
|
267 |
+
return !!(obj && obj.constructor && obj.call && obj.apply);
|
268 |
+
}
|
269 |
+
|
270 |
+
function isArray(obj) {
|
271 |
+
return toString.call(obj) === '[object Array]';
|
272 |
+
}
|
273 |
+
|
274 |
+
// Give the init function the Froogaloop prototype for later instantiation
|
275 |
+
Froogaloop.fn.init.prototype = Froogaloop.fn;
|
276 |
+
|
277 |
+
// Listens for the message event.
|
278 |
+
// W3C
|
279 |
+
if (window.addEventListener) {
|
280 |
+
window.addEventListener('message', onMessageReceived, false);
|
281 |
+
}
|
282 |
+
// IE
|
283 |
+
else {
|
284 |
+
window.attachEvent('onmessage', onMessageReceived);
|
285 |
+
}
|
286 |
+
|
287 |
+
// Expose froogaloop to the global object
|
288 |
+
return (window.Froogaloop = window.$f = Froogaloop);
|
289 |
+
|
290 |
+
})();
|
js/jquery/froogaloop.min.js
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
; // for better merging
|
2 |
+
var Froogaloop=function(){function e(a){return new e.fn.init(a)}function h(a,c,b){if(!b.contentWindow.postMessage)return!1;var f=b.getAttribute("src").split("?")[0],a=JSON.stringify({method:a,value:c});"//"===f.substr(0,2)&&(f=window.location.protocol+f);b.contentWindow.postMessage(a,f)}function j(a){var c,b;try{c=JSON.parse(a.data),b=c.event||c.method}catch(f){}"ready"==b&&!i&&(i=!0);if(a.origin!=k)return!1;var a=c.value,e=c.data,g=""===g?null:c.player_id;c=g?d[g][b]:d[b];b=[];if(!c)return!1;void 0!==
|
3 |
+
a&&b.push(a);e&&b.push(e);g&&b.push(g);return 0<b.length?c.apply(null,b):c.call()}function l(a,c,b){b?(d[b]||(d[b]={}),d[b][a]=c):d[a]=c}var d={},i=!1,k="";e.fn=e.prototype={element:null,init:function(a){"string"===typeof a&&(a=document.getElementById(a));this.element=a;a=this.element.getAttribute("src");"//"===a.substr(0,2)&&(a=window.location.protocol+a);for(var a=a.split("/"),c="",b=0,f=a.length;b<f;b++){if(3>b)c+=a[b];else break;2>b&&(c+="/")}k=c;return this},api:function(a,c){if(!this.element||
|
4 |
+
!a)return!1;var b=this.element,f=""!==b.id?b.id:null,d=!c||!c.constructor||!c.call||!c.apply?c:null,e=c&&c.constructor&&c.call&&c.apply?c:null;e&&l(a,e,f);h(a,d,b);return this},addEvent:function(a,c){if(!this.element)return!1;var b=this.element,d=""!==b.id?b.id:null;l(a,c,d);"ready"!=a?h("addEventListener",a,b):"ready"==a&&i&&c.call(null,d);return this},removeEvent:function(a){if(!this.element)return!1;var c=this.element,b;a:{if((b=""!==c.id?c.id:null)&&d[b]){if(!d[b][a]){b=!1;break a}d[b][a]=null}else{if(!d[a]){b=
|
5 |
+
!1;break a}d[a]=null}b=!0}"ready"!=a&&b&&h("removeEventListener",a,c)}};e.fn.init.prototype=e.fn;window.addEventListener?window.addEventListener("message",j,!1):window.attachEvent("onmessage",j);return window.Froogaloop=window.$f=e}();
|
js/jquery/history.js
CHANGED
@@ -1026,15 +1026,20 @@
|
|
1026 |
var result = str;
|
1027 |
|
1028 |
// Unescape hash
|
1029 |
-
var tmp;
|
1030 |
-
|
1031 |
-
tmp = window.unescape(result);
|
1032 |
if ( tmp === result ) {
|
|
|
1033 |
break;
|
1034 |
}
|
1035 |
result = tmp;
|
1036 |
}
|
1037 |
|
|
|
|
|
|
|
|
|
1038 |
// Return result
|
1039 |
return result;
|
1040 |
};
|
1026 |
var result = str;
|
1027 |
|
1028 |
// Unescape hash
|
1029 |
+
var tmp, success = false;
|
1030 |
+
for (var i = 0; i < 3; i++) {
|
1031 |
+
tmp = window.unescape(encodeURIComponent(result));
|
1032 |
if ( tmp === result ) {
|
1033 |
+
success = true;
|
1034 |
break;
|
1035 |
}
|
1036 |
result = tmp;
|
1037 |
}
|
1038 |
|
1039 |
+
if (!success) {
|
1040 |
+
throw 'History.unescapeString(): unable to unescape ' + str;
|
1041 |
+
}
|
1042 |
+
|
1043 |
// Return result
|
1044 |
return result;
|
1045 |
};
|
js/jquery/jquery-1.7.2.min.js
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
/*! jQuery v1.7.2 jquery.com | jquery.org/license */
|
2 |
-
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
|
3 |
-
a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
|
4 |
-
.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
|
5 |
-
|
6 |
-
jQuery.noConflict();
|
|
|
|
|
|
|
|
|
|
|
|
js/jquery/jquery-ui.js
CHANGED
@@ -1,43 +1,28 @@
|
|
1 |
-
/*!
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
* http://jquery.org/license
|
7 |
-
*
|
8 |
-
* http://docs.jquery.com/UI
|
9 |
-
*/
|
10 |
-
;(function( $, undefined ) {
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
15 |
$.ui = $.ui || {};
|
16 |
-
if ( $.ui.version ) {
|
17 |
-
return;
|
18 |
-
}
|
19 |
|
20 |
$.extend( $.ui, {
|
21 |
-
version: "1.
|
22 |
|
23 |
keyCode: {
|
24 |
-
ALT: 18,
|
25 |
BACKSPACE: 8,
|
26 |
-
CAPS_LOCK: 20,
|
27 |
COMMA: 188,
|
28 |
-
COMMAND: 91,
|
29 |
-
COMMAND_LEFT: 91, // COMMAND
|
30 |
-
COMMAND_RIGHT: 93,
|
31 |
-
CONTROL: 17,
|
32 |
DELETE: 46,
|
33 |
DOWN: 40,
|
34 |
END: 35,
|
35 |
ENTER: 13,
|
36 |
ESCAPE: 27,
|
37 |
HOME: 36,
|
38 |
-
INSERT: 45,
|
39 |
LEFT: 37,
|
40 |
-
MENU: 93, // COMMAND_RIGHT
|
41 |
NUMPAD_ADD: 107,
|
42 |
NUMPAD_DECIMAL: 110,
|
43 |
NUMPAD_DIVIDE: 111,
|
@@ -48,46 +33,43 @@ $.extend( $.ui, {
|
|
48 |
PAGE_UP: 33,
|
49 |
PERIOD: 190,
|
50 |
RIGHT: 39,
|
51 |
-
SHIFT: 16,
|
52 |
SPACE: 32,
|
53 |
TAB: 9,
|
54 |
-
UP: 38
|
55 |
-
WINDOWS: 91 // COMMAND
|
56 |
}
|
57 |
});
|
58 |
|
59 |
// plugins
|
60 |
$.fn.extend({
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
},
|
77 |
|
78 |
scrollParent: function() {
|
79 |
var scrollParent;
|
80 |
-
if (($.
|
81 |
scrollParent = this.parents().filter(function() {
|
82 |
-
return (/(relative|absolute|fixed)/).test($.
|
83 |
}).eq(0);
|
84 |
} else {
|
85 |
scrollParent = this.parents().filter(function() {
|
86 |
-
return (/(auto|scroll)/).test($.
|
87 |
}).eq(0);
|
88 |
}
|
89 |
|
90 |
-
return (/fixed/).test(this.css(
|
91 |
},
|
92 |
|
93 |
zIndex: function( zIndex ) {
|
@@ -119,95 +101,63 @@ $.fn.extend({
|
|
119 |
return 0;
|
120 |
},
|
121 |
|
122 |
-
|
123 |
-
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
|
124 |
-
".ui-disableSelection", function( event ) {
|
125 |
-
event.preventDefault();
|
126 |
-
});
|
127 |
-
},
|
128 |
-
|
129 |
-
enableSelection: function() {
|
130 |
-
return this.unbind( ".ui-disableSelection" );
|
131 |
-
}
|
132 |
-
});
|
133 |
-
|
134 |
-
$.each( [ "Width", "Height" ], function( i, name ) {
|
135 |
-
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
|
136 |
-
type = name.toLowerCase(),
|
137 |
-
orig = {
|
138 |
-
innerWidth: $.fn.innerWidth,
|
139 |
-
innerHeight: $.fn.innerHeight,
|
140 |
-
outerWidth: $.fn.outerWidth,
|
141 |
-
outerHeight: $.fn.outerHeight
|
142 |
-
};
|
143 |
-
|
144 |
-
function reduce( elem, size, border, margin ) {
|
145 |
-
$.each( side, function() {
|
146 |
-
size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
|
147 |
-
if ( border ) {
|
148 |
-
size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
|
149 |
-
}
|
150 |
-
if ( margin ) {
|
151 |
-
size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
|
152 |
-
}
|
153 |
-
});
|
154 |
-
return size;
|
155 |
-
}
|
156 |
-
|
157 |
-
$.fn[ "inner" + name ] = function( size ) {
|
158 |
-
if ( size === undefined ) {
|
159 |
-
return orig[ "inner" + name ].call( this );
|
160 |
-
}
|
161 |
-
|
162 |
return this.each(function() {
|
163 |
-
|
|
|
|
|
164 |
});
|
165 |
-
}
|
166 |
-
|
167 |
-
$.fn[ "outer" + name] = function( size, margin ) {
|
168 |
-
if ( typeof size !== "number" ) {
|
169 |
-
return orig[ "outer" + name ].call( this, size );
|
170 |
-
}
|
171 |
|
|
|
172 |
return this.each(function() {
|
173 |
-
|
|
|
|
|
174 |
});
|
175 |
-
}
|
176 |
});
|
177 |
|
178 |
// selectors
|
179 |
function focusable( element, isTabIndexNotNaN ) {
|
180 |
-
var
|
|
|
181 |
if ( "area" === nodeName ) {
|
182 |
-
|
183 |
-
|
184 |
-
img;
|
185 |
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
|
186 |
return false;
|
187 |
}
|
188 |
img = $( "img[usemap=#" + mapName + "]" )[0];
|
189 |
return !!img && visible( img );
|
190 |
}
|
191 |
-
return ( /input|select|textarea|button|object/.test( nodeName )
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
// the element and all of its ancestors must be visible
|
197 |
-
|
198 |
}
|
199 |
|
200 |
function visible( element ) {
|
201 |
-
return
|
202 |
-
|
203 |
-
$.
|
204 |
-
|
205 |
}
|
206 |
|
207 |
$.extend( $.expr[ ":" ], {
|
208 |
-
data:
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
focusable: function( element ) {
|
213 |
return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
|
@@ -220,77 +170,137 @@ $.extend( $.expr[ ":" ], {
|
|
220 |
}
|
221 |
});
|
222 |
|
223 |
-
// support
|
224 |
-
|
225 |
-
|
226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
});
|
|
|
234 |
|
235 |
-
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
// deprecated
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
$.extend( $.ui, {
|
249 |
// $.ui.plugin is deprecated. Use the proxy pattern instead.
|
250 |
plugin: {
|
251 |
add: function( module, option, set ) {
|
252 |
-
var
|
253 |
-
|
|
|
254 |
proto.plugins[ i ] = proto.plugins[ i ] || [];
|
255 |
proto.plugins[ i ].push( [ option, set[ i ] ] );
|
256 |
}
|
257 |
},
|
258 |
call: function( instance, name, args ) {
|
259 |
-
var
|
260 |
-
|
|
|
261 |
return;
|
262 |
}
|
263 |
-
|
264 |
-
for (
|
265 |
if ( instance.options[ set[ i ][ 0 ] ] ) {
|
266 |
set[ i ][ 1 ].apply( instance.element, args );
|
267 |
}
|
268 |
}
|
269 |
}
|
270 |
},
|
271 |
-
|
272 |
-
// will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
|
273 |
-
contains: function( a, b ) {
|
274 |
-
return document.compareDocumentPosition ?
|
275 |
-
a.compareDocumentPosition( b ) & 16 :
|
276 |
-
a !== b && a.contains( b );
|
277 |
-
},
|
278 |
-
|
279 |
// only used by resizable
|
280 |
hasScroll: function( el, a ) {
|
281 |
-
|
282 |
//If overflow is hidden, the element might have extra content, but the user wants to hide it
|
283 |
if ( $( el ).css( "overflow" ) === "hidden") {
|
284 |
return false;
|
285 |
}
|
286 |
-
|
287 |
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
|
288 |
has = false;
|
289 |
-
|
290 |
if ( el[ scroll ] > 0 ) {
|
291 |
return true;
|
292 |
}
|
293 |
-
|
294 |
// TODO: determine which cases actually cause this to happen
|
295 |
// if the element doesn't have the scroll set, see if it's possible to
|
296 |
// set the scroll
|
@@ -298,65 +308,33 @@ $.extend( $.ui, {
|
|
298 |
has = ( el[ scroll ] > 0 );
|
299 |
el[ scroll ] = 0;
|
300 |
return has;
|
301 |
-
},
|
302 |
-
|
303 |
-
// these are odd functions, fix the API or move into individual plugins
|
304 |
-
isOverAxis: function( x, reference, size ) {
|
305 |
-
//Determines when x coordinate is over "b" element axis
|
306 |
-
return ( x > reference ) && ( x < ( reference + size ) );
|
307 |
-
},
|
308 |
-
isOver: function( y, x, top, left, height, width ) {
|
309 |
-
//Determines when x, y coordinates is over "b" element
|
310 |
-
return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
|
311 |
}
|
312 |
});
|
313 |
|
314 |
})( jQuery );
|
315 |
-
|
316 |
-
* jQuery UI Widget 1.8.17
|
317 |
-
*
|
318 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
319 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
320 |
-
* http://jquery.org/license
|
321 |
-
*
|
322 |
-
* http://docs.jquery.com/UI/Widget
|
323 |
-
*/
|
324 |
(function( $, undefined ) {
|
325 |
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
} else {
|
339 |
-
var _remove = $.fn.remove;
|
340 |
-
$.fn.remove = function( selector, keepData ) {
|
341 |
-
return this.each(function() {
|
342 |
-
if ( !keepData ) {
|
343 |
-
if ( !selector || $.filter( selector, [ this ] ).length ) {
|
344 |
-
$( "*", this ).add( [ this ] ).each(function() {
|
345 |
-
try {
|
346 |
-
$( this ).triggerHandler( "remove" );
|
347 |
-
// http://bugs.jquery.com/ticket/8235
|
348 |
-
} catch( e ) {}
|
349 |
-
});
|
350 |
-
}
|
351 |
-
}
|
352 |
-
return _remove.call( $(this), selector, keepData );
|
353 |
-
});
|
354 |
-
};
|
355 |
-
}
|
356 |
|
357 |
$.widget = function( name, base, prototype ) {
|
358 |
-
var
|
359 |
-
|
|
|
|
|
|
|
|
|
360 |
name = name.split( "." )[ 1 ];
|
361 |
fullName = namespace + "-" + name;
|
362 |
|
@@ -366,81 +344,167 @@ $.widget = function( name, base, prototype ) {
|
|
366 |
}
|
367 |
|
368 |
// create selector for plugin
|
369 |
-
$.expr[ ":" ][ fullName ] = function( elem ) {
|
370 |
-
return !!$.data( elem,
|
371 |
};
|
372 |
|
373 |
$[ namespace ] = $[ namespace ] || {};
|
374 |
-
$[ namespace ][ name ]
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
// allow instantiation without initializing for simple inheritance
|
|
|
376 |
if ( arguments.length ) {
|
377 |
this._createWidget( options, element );
|
378 |
}
|
379 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
|
381 |
-
|
382 |
// we need to make the options hash a property directly on the new instance
|
383 |
// otherwise we'll modify the options hash on the prototype that we're
|
384 |
// inheriting from
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
namespace: namespace,
|
393 |
widgetName: name,
|
394 |
-
|
395 |
-
|
396 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
|
398 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
};
|
400 |
|
401 |
$.widget.bridge = function( name, object ) {
|
|
|
402 |
$.fn[ name ] = function( options ) {
|
403 |
var isMethodCall = typeof options === "string",
|
404 |
-
args =
|
405 |
returnValue = this;
|
406 |
|
407 |
// allow multiple hashes to be passed on init
|
408 |
options = !isMethodCall && args.length ?
|
409 |
-
$.extend.apply( null, [
|
410 |
options;
|
411 |
|
412 |
-
// prevent calls to internal methods
|
413 |
-
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
|
414 |
-
return returnValue;
|
415 |
-
}
|
416 |
-
|
417 |
if ( isMethodCall ) {
|
418 |
this.each(function() {
|
419 |
-
var
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
// throw "no such method '" + options + "' for " + name + " widget instance";
|
430 |
-
// }
|
431 |
-
// var methodValue = instance[ options ].apply( instance, args );
|
432 |
if ( methodValue !== instance && methodValue !== undefined ) {
|
433 |
-
returnValue = methodValue
|
|
|
|
|
434 |
return false;
|
435 |
}
|
436 |
});
|
437 |
} else {
|
438 |
this.each(function() {
|
439 |
-
var instance = $.data( this,
|
440 |
if ( instance ) {
|
441 |
instance.option( options || {} )._init();
|
442 |
} else {
|
443 |
-
$.data( this,
|
444 |
}
|
445 |
});
|
446 |
}
|
@@ -449,74 +513,123 @@ $.widget.bridge = function( name, object ) {
|
|
449 |
};
|
450 |
};
|
451 |
|
452 |
-
$.Widget = function( options, element ) {
|
453 |
-
|
454 |
-
if ( arguments.length ) {
|
455 |
-
this._createWidget( options, element );
|
456 |
-
}
|
457 |
-
};
|
458 |
|
459 |
$.Widget.prototype = {
|
460 |
widgetName: "widget",
|
461 |
widgetEventPrefix: "",
|
|
|
462 |
options: {
|
463 |
-
disabled: false
|
|
|
|
|
|
|
464 |
},
|
465 |
_createWidget: function( options, element ) {
|
466 |
-
|
467 |
-
// so that it's stored even before the _create function runs
|
468 |
-
$.data( element, this.widgetName, this );
|
469 |
this.element = $( element );
|
470 |
-
this.
|
|
|
|
|
471 |
this.options,
|
472 |
this._getCreateOptions(),
|
473 |
options );
|
474 |
|
475 |
-
|
476 |
-
this.
|
477 |
-
|
478 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
|
480 |
this._create();
|
481 |
-
this._trigger( "create" );
|
482 |
this._init();
|
483 |
},
|
484 |
-
_getCreateOptions:
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
_init: function() {},
|
489 |
|
490 |
destroy: function() {
|
|
|
|
|
|
|
491 |
this.element
|
492 |
-
.unbind(
|
493 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
494 |
this.widget()
|
495 |
-
.unbind(
|
496 |
.removeAttr( "aria-disabled" )
|
497 |
.removeClass(
|
498 |
-
this.
|
499 |
"ui-state-disabled" );
|
|
|
|
|
|
|
|
|
|
|
500 |
},
|
|
|
501 |
|
502 |
widget: function() {
|
503 |
return this.element;
|
504 |
},
|
505 |
|
506 |
option: function( key, value ) {
|
507 |
-
var options = key
|
|
|
|
|
|
|
508 |
|
509 |
if ( arguments.length === 0 ) {
|
510 |
// don't return a reference to the internal hash
|
511 |
-
return $.extend( {}, this.options );
|
512 |
}
|
513 |
|
514 |
-
if
|
515 |
-
|
516 |
-
return this.options[ key ];
|
517 |
-
}
|
518 |
options = {};
|
519 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
}
|
521 |
|
522 |
this._setOptions( options );
|
@@ -524,10 +637,11 @@ $.Widget.prototype = {
|
|
524 |
return this;
|
525 |
},
|
526 |
_setOptions: function( options ) {
|
527 |
-
var
|
528 |
-
|
529 |
-
|
530 |
-
|
|
|
531 |
|
532 |
return this;
|
533 |
},
|
@@ -536,10 +650,10 @@ $.Widget.prototype = {
|
|
536 |
|
537 |
if ( key === "disabled" ) {
|
538 |
this.widget()
|
539 |
-
|
540 |
-
this.widgetBaseClass + "-disabled" + " " +
|
541 |
-
"ui-state-disabled" )
|
542 |
.attr( "aria-disabled", value );
|
|
|
|
|
543 |
}
|
544 |
|
545 |
return this;
|
@@ -552,6 +666,97 @@ $.Widget.prototype = {
|
|
552 |
return this._setOption( "disabled", true );
|
553 |
},
|
554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
555 |
_trigger: function( type, event, data ) {
|
556 |
var prop, orig,
|
557 |
callback = this.options[ type ];
|
@@ -576,49 +781,74 @@ $.Widget.prototype = {
|
|
576 |
}
|
577 |
|
578 |
this.element.trigger( event, data );
|
579 |
-
|
580 |
-
|
581 |
-
callback.call( this.element[0], event, data ) === false ||
|
582 |
event.isDefaultPrevented() );
|
583 |
}
|
584 |
};
|
585 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
})( jQuery );
|
587 |
-
|
588 |
-
* jQuery UI Mouse 1.8.17
|
589 |
-
*
|
590 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
591 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
592 |
-
* http://jquery.org/license
|
593 |
-
*
|
594 |
-
* http://docs.jquery.com/UI/Mouse
|
595 |
-
*
|
596 |
-
* Depends:
|
597 |
-
* jquery.ui.widget.js
|
598 |
-
*/
|
599 |
(function( $, undefined ) {
|
600 |
|
601 |
var mouseHandled = false;
|
602 |
-
$( document ).mouseup( function(
|
603 |
mouseHandled = false;
|
604 |
});
|
605 |
|
606 |
$.widget("ui.mouse", {
|
|
|
607 |
options: {
|
608 |
-
cancel:
|
609 |
distance: 1,
|
610 |
delay: 0
|
611 |
},
|
612 |
_mouseInit: function() {
|
613 |
-
var
|
614 |
|
615 |
this.element
|
616 |
-
.bind(
|
617 |
-
return
|
618 |
})
|
619 |
-
.bind(
|
620 |
-
if (true === $.data(event.target,
|
621 |
-
|
622 |
event.stopImmediatePropagation();
|
623 |
return false;
|
624 |
}
|
@@ -630,23 +860,28 @@ $.widget("ui.mouse", {
|
|
630 |
// TODO: make sure destroying one instance of mouse doesn't mess with
|
631 |
// other instances of mouse
|
632 |
_mouseDestroy: function() {
|
633 |
-
this.element.unbind(
|
|
|
|
|
|
|
|
|
|
|
634 |
},
|
635 |
|
636 |
_mouseDown: function(event) {
|
637 |
// don't let more than one widget handle mouseStart
|
638 |
-
if( mouseHandled ) { return }
|
639 |
|
640 |
// we may have missed mouseup (out of window)
|
641 |
(this._mouseStarted && this._mouseUp(event));
|
642 |
|
643 |
this._mouseDownEvent = event;
|
644 |
|
645 |
-
var
|
646 |
-
btnIsLeft = (event.which
|
647 |
// event.target.nodeName works around a bug in IE 8 with
|
648 |
// disabled inputs (#7620)
|
649 |
-
elIsCancel = (typeof this.options.cancel
|
650 |
if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
|
651 |
return true;
|
652 |
}
|
@@ -654,7 +889,7 @@ $.widget("ui.mouse", {
|
|
654 |
this.mouseDelayMet = !this.options.delay;
|
655 |
if (!this.mouseDelayMet) {
|
656 |
this._mouseDelayTimer = setTimeout(function() {
|
657 |
-
|
658 |
}, this.options.delay);
|
659 |
}
|
660 |
|
@@ -667,30 +902,30 @@ $.widget("ui.mouse", {
|
|
667 |
}
|
668 |
|
669 |
// Click event may never have fired (Gecko & Opera)
|
670 |
-
if (true === $.data(event.target, this.widgetName +
|
671 |
-
$.removeData(event.target, this.widgetName +
|
672 |
}
|
673 |
|
674 |
// these delegates are required to keep context
|
675 |
this._mouseMoveDelegate = function(event) {
|
676 |
-
return
|
677 |
};
|
678 |
this._mouseUpDelegate = function(event) {
|
679 |
-
return
|
680 |
};
|
681 |
$(document)
|
682 |
-
.bind(
|
683 |
-
.bind(
|
684 |
|
685 |
event.preventDefault();
|
686 |
-
|
687 |
mouseHandled = true;
|
688 |
return true;
|
689 |
},
|
690 |
|
691 |
_mouseMove: function(event) {
|
692 |
// IE mouseup check - mouseup happened when mouse was out of window
|
693 |
-
if ($.
|
694 |
return this._mouseUp(event);
|
695 |
}
|
696 |
|
@@ -710,14 +945,14 @@ $.widget("ui.mouse", {
|
|
710 |
|
711 |
_mouseUp: function(event) {
|
712 |
$(document)
|
713 |
-
.unbind(
|
714 |
-
.unbind(
|
715 |
|
716 |
if (this._mouseStarted) {
|
717 |
this._mouseStarted = false;
|
718 |
|
719 |
-
if (event.target
|
720 |
-
|
721 |
}
|
722 |
|
723 |
this._mouseStop(event);
|
@@ -734,383 +969,74 @@ $.widget("ui.mouse", {
|
|
734 |
);
|
735 |
},
|
736 |
|
737 |
-
_mouseDelayMet: function(event) {
|
738 |
return this.mouseDelayMet;
|
739 |
},
|
740 |
|
741 |
// These are placeholder methods, to be overriden by extending plugin
|
742 |
-
_mouseStart: function(event) {},
|
743 |
-
_mouseDrag: function(event) {},
|
744 |
-
_mouseStop: function(event) {},
|
745 |
-
_mouseCapture: function(event) { return true; }
|
746 |
});
|
747 |
|
748 |
})(jQuery);
|
749 |
-
|
750 |
-
* jQuery UI Position 1.8.17
|
751 |
-
*
|
752 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
753 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
754 |
-
* http://jquery.org/license
|
755 |
-
*
|
756 |
-
* http://docs.jquery.com/UI/Position
|
757 |
-
*/
|
758 |
(function( $, undefined ) {
|
759 |
|
760 |
-
$.ui
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
|
769 |
-
|
770 |
-
|
771 |
-
return _position.apply( this, arguments );
|
772 |
-
}
|
773 |
-
|
774 |
-
// make a copy, we don't want to modify arguments
|
775 |
-
options = $.extend( {}, options );
|
776 |
-
|
777 |
-
var target = $( options.of ),
|
778 |
-
targetElem = target[0],
|
779 |
-
collision = ( options.collision || "flip" ).split( " " ),
|
780 |
-
offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
|
781 |
-
targetWidth,
|
782 |
-
targetHeight,
|
783 |
-
basePosition;
|
784 |
-
|
785 |
-
if ( targetElem.nodeType === 9 ) {
|
786 |
-
targetWidth = target.width();
|
787 |
-
targetHeight = target.height();
|
788 |
-
basePosition = { top: 0, left: 0 };
|
789 |
-
// TODO: use $.isWindow() in 1.9
|
790 |
-
} else if ( targetElem.setTimeout ) {
|
791 |
-
targetWidth = target.width();
|
792 |
-
targetHeight = target.height();
|
793 |
-
basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
|
794 |
-
} else if ( targetElem.preventDefault ) {
|
795 |
-
// force left top to allow flipping
|
796 |
-
options.at = "left top";
|
797 |
-
targetWidth = targetHeight = 0;
|
798 |
-
basePosition = { top: options.of.pageY, left: options.of.pageX };
|
799 |
-
} else {
|
800 |
-
targetWidth = target.outerWidth();
|
801 |
-
targetHeight = target.outerHeight();
|
802 |
-
basePosition = target.offset();
|
803 |
-
}
|
804 |
-
|
805 |
-
// force my and at to have valid horizontal and veritcal positions
|
806 |
-
// if a value is missing or invalid, it will be converted to center
|
807 |
-
$.each( [ "my", "at" ], function() {
|
808 |
-
var pos = ( options[this] || "" ).split( " " );
|
809 |
-
if ( pos.length === 1) {
|
810 |
-
pos = horizontalPositions.test( pos[0] ) ?
|
811 |
-
pos.concat( [center] ) :
|
812 |
-
verticalPositions.test( pos[0] ) ?
|
813 |
-
[ center ].concat( pos ) :
|
814 |
-
[ center, center ];
|
815 |
-
}
|
816 |
-
pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
|
817 |
-
pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
|
818 |
-
options[ this ] = pos;
|
819 |
-
});
|
820 |
-
|
821 |
-
// normalize collision option
|
822 |
-
if ( collision.length === 1 ) {
|
823 |
-
collision[ 1 ] = collision[ 0 ];
|
824 |
-
}
|
825 |
-
|
826 |
-
// normalize offset option
|
827 |
-
offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
|
828 |
-
if ( offset.length === 1 ) {
|
829 |
-
offset[ 1 ] = offset[ 0 ];
|
830 |
-
}
|
831 |
-
offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
|
832 |
-
|
833 |
-
if ( options.at[0] === "right" ) {
|
834 |
-
basePosition.left += targetWidth;
|
835 |
-
} else if ( options.at[0] === center ) {
|
836 |
-
basePosition.left += targetWidth / 2;
|
837 |
-
}
|
838 |
-
|
839 |
-
if ( options.at[1] === "bottom" ) {
|
840 |
-
basePosition.top += targetHeight;
|
841 |
-
} else if ( options.at[1] === center ) {
|
842 |
-
basePosition.top += targetHeight / 2;
|
843 |
-
}
|
844 |
-
|
845 |
-
basePosition.left += offset[ 0 ];
|
846 |
-
basePosition.top += offset[ 1 ];
|
847 |
-
|
848 |
-
return this.each(function() {
|
849 |
-
var elem = $( this ),
|
850 |
-
elemWidth = elem.outerWidth(),
|
851 |
-
elemHeight = elem.outerHeight(),
|
852 |
-
marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
|
853 |
-
marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
|
854 |
-
collisionWidth = elemWidth + marginLeft +
|
855 |
-
( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
|
856 |
-
collisionHeight = elemHeight + marginTop +
|
857 |
-
( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
|
858 |
-
position = $.extend( {}, basePosition ),
|
859 |
-
collisionPosition;
|
860 |
-
|
861 |
-
if ( options.my[0] === "right" ) {
|
862 |
-
position.left -= elemWidth;
|
863 |
-
} else if ( options.my[0] === center ) {
|
864 |
-
position.left -= elemWidth / 2;
|
865 |
-
}
|
866 |
-
|
867 |
-
if ( options.my[1] === "bottom" ) {
|
868 |
-
position.top -= elemHeight;
|
869 |
-
} else if ( options.my[1] === center ) {
|
870 |
-
position.top -= elemHeight / 2;
|
871 |
-
}
|
872 |
-
|
873 |
-
// prevent fractions if jQuery version doesn't support them (see #5280)
|
874 |
-
if ( !support.fractions ) {
|
875 |
-
position.left = Math.round( position.left );
|
876 |
-
position.top = Math.round( position.top );
|
877 |
-
}
|
878 |
-
|
879 |
-
collisionPosition = {
|
880 |
-
left: position.left - marginLeft,
|
881 |
-
top: position.top - marginTop
|
882 |
-
};
|
883 |
-
|
884 |
-
$.each( [ "left", "top" ], function( i, dir ) {
|
885 |
-
if ( $.ui.position[ collision[i] ] ) {
|
886 |
-
$.ui.position[ collision[i] ][ dir ]( position, {
|
887 |
-
targetWidth: targetWidth,
|
888 |
-
targetHeight: targetHeight,
|
889 |
-
elemWidth: elemWidth,
|
890 |
-
elemHeight: elemHeight,
|
891 |
-
collisionPosition: collisionPosition,
|
892 |
-
collisionWidth: collisionWidth,
|
893 |
-
collisionHeight: collisionHeight,
|
894 |
-
offset: offset,
|
895 |
-
my: options.my,
|
896 |
-
at: options.at
|
897 |
-
});
|
898 |
-
}
|
899 |
-
});
|
900 |
-
|
901 |
-
if ( $.fn.bgiframe ) {
|
902 |
-
elem.bgiframe();
|
903 |
-
}
|
904 |
-
elem.offset( $.extend( position, { using: options.using } ) );
|
905 |
-
});
|
906 |
-
};
|
907 |
-
|
908 |
-
$.ui.position = {
|
909 |
-
fit: {
|
910 |
-
left: function( position, data ) {
|
911 |
-
var win = $( window ),
|
912 |
-
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
|
913 |
-
position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
|
914 |
-
},
|
915 |
-
top: function( position, data ) {
|
916 |
-
var win = $( window ),
|
917 |
-
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
|
918 |
-
position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
|
919 |
-
}
|
920 |
-
},
|
921 |
-
|
922 |
-
flip: {
|
923 |
-
left: function( position, data ) {
|
924 |
-
if ( data.at[0] === center ) {
|
925 |
-
return;
|
926 |
-
}
|
927 |
-
var win = $( window ),
|
928 |
-
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
|
929 |
-
myOffset = data.my[ 0 ] === "left" ?
|
930 |
-
-data.elemWidth :
|
931 |
-
data.my[ 0 ] === "right" ?
|
932 |
-
data.elemWidth :
|
933 |
-
0,
|
934 |
-
atOffset = data.at[ 0 ] === "left" ?
|
935 |
-
data.targetWidth :
|
936 |
-
-data.targetWidth,
|
937 |
-
offset = -2 * data.offset[ 0 ];
|
938 |
-
position.left += data.collisionPosition.left < 0 ?
|
939 |
-
myOffset + atOffset + offset :
|
940 |
-
over > 0 ?
|
941 |
-
myOffset + atOffset + offset :
|
942 |
-
0;
|
943 |
-
},
|
944 |
-
top: function( position, data ) {
|
945 |
-
if ( data.at[1] === center ) {
|
946 |
-
return;
|
947 |
-
}
|
948 |
-
var win = $( window ),
|
949 |
-
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
|
950 |
-
myOffset = data.my[ 1 ] === "top" ?
|
951 |
-
-data.elemHeight :
|
952 |
-
data.my[ 1 ] === "bottom" ?
|
953 |
-
data.elemHeight :
|
954 |
-
0,
|
955 |
-
atOffset = data.at[ 1 ] === "top" ?
|
956 |
-
data.targetHeight :
|
957 |
-
-data.targetHeight,
|
958 |
-
offset = -2 * data.offset[ 1 ];
|
959 |
-
position.top += data.collisionPosition.top < 0 ?
|
960 |
-
myOffset + atOffset + offset :
|
961 |
-
over > 0 ?
|
962 |
-
myOffset + atOffset + offset :
|
963 |
-
0;
|
964 |
}
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
// offset setter from jQuery 1.4
|
969 |
-
if ( !$.offset.setOffset ) {
|
970 |
-
$.offset.setOffset = function( elem, options ) {
|
971 |
-
// set position first, in-case top/left are set even on static elem
|
972 |
-
if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
|
973 |
-
elem.style.position = "relative";
|
974 |
-
}
|
975 |
-
var curElem = $( elem ),
|
976 |
-
curOffset = curElem.offset(),
|
977 |
-
curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
|
978 |
-
curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
|
979 |
-
props = {
|
980 |
-
top: (options.top - curOffset.top) + curTop,
|
981 |
-
left: (options.left - curOffset.left) + curLeft
|
982 |
-
};
|
983 |
-
|
984 |
-
if ( 'using' in options ) {
|
985 |
-
options.using.call( elem, props );
|
986 |
-
} else {
|
987 |
-
curElem.css( props );
|
988 |
}
|
989 |
-
|
990 |
-
|
991 |
-
$.fn.offset = function( options ) {
|
992 |
-
var elem = this[ 0 ];
|
993 |
-
if ( !elem || !elem.ownerDocument ) { return null; }
|
994 |
-
if ( options ) {
|
995 |
-
return this.each(function() {
|
996 |
-
$.offset.setOffset( this, options );
|
997 |
-
});
|
998 |
}
|
999 |
-
return _offset.call( this );
|
1000 |
-
};
|
1001 |
-
}
|
1002 |
-
|
1003 |
-
// fraction support test (older versions of jQuery don't support fractions)
|
1004 |
-
(function () {
|
1005 |
-
var body = document.getElementsByTagName( "body" )[ 0 ],
|
1006 |
-
div = document.createElement( "div" ),
|
1007 |
-
testElement, testElementParent, testElementStyle, offset, offsetTotal;
|
1008 |
-
|
1009 |
-
//Create a "fake body" for testing based on method used in jQuery.support
|
1010 |
-
testElement = document.createElement( body ? "div" : "body" );
|
1011 |
-
testElementStyle = {
|
1012 |
-
visibility: "hidden",
|
1013 |
-
width: 0,
|
1014 |
-
height: 0,
|
1015 |
-
border: 0,
|
1016 |
-
margin: 0,
|
1017 |
-
background: "none"
|
1018 |
-
};
|
1019 |
-
if ( body ) {
|
1020 |
-
jQuery.extend( testElementStyle, {
|
1021 |
-
position: "absolute",
|
1022 |
-
left: "-1000px",
|
1023 |
-
top: "-1000px"
|
1024 |
-
});
|
1025 |
-
}
|
1026 |
-
for ( var i in testElementStyle ) {
|
1027 |
-
testElement.style[ i ] = testElementStyle[ i ];
|
1028 |
-
}
|
1029 |
-
testElement.appendChild( div );
|
1030 |
-
testElementParent = body || document.documentElement;
|
1031 |
-
testElementParent.insertBefore( testElement, testElementParent.firstChild );
|
1032 |
-
|
1033 |
-
div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";
|
1034 |
-
|
1035 |
-
offset = $( div ).offset( function( _, offset ) {
|
1036 |
-
return offset;
|
1037 |
-
}).offset();
|
1038 |
-
|
1039 |
-
testElement.innerHTML = "";
|
1040 |
-
testElementParent.removeChild( testElement );
|
1041 |
-
|
1042 |
-
offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 );
|
1043 |
-
support.fractions = offsetTotal > 21 && offsetTotal < 22;
|
1044 |
-
})();
|
1045 |
-
|
1046 |
-
}( jQuery ));
|
1047 |
-
/*
|
1048 |
-
* jQuery UI Draggable 1.8.17
|
1049 |
-
*
|
1050 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
1051 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
1052 |
-
* http://jquery.org/license
|
1053 |
-
*
|
1054 |
-
* http://docs.jquery.com/UI/Draggables
|
1055 |
-
*
|
1056 |
-
* Depends:
|
1057 |
-
* jquery.ui.core.js
|
1058 |
-
* jquery.ui.mouse.js
|
1059 |
-
* jquery.ui.widget.js
|
1060 |
-
*/
|
1061 |
-
(function( $, undefined ) {
|
1062 |
-
|
1063 |
-
$.widget("ui.draggable", $.ui.mouse, {
|
1064 |
-
widgetEventPrefix: "drag",
|
1065 |
-
options: {
|
1066 |
-
addClasses: true,
|
1067 |
-
appendTo: "parent",
|
1068 |
-
axis: false,
|
1069 |
-
connectToSortable: false,
|
1070 |
-
containment: false,
|
1071 |
-
cursor: "auto",
|
1072 |
-
cursorAt: false,
|
1073 |
-
grid: false,
|
1074 |
-
handle: false,
|
1075 |
-
helper: "original",
|
1076 |
-
iframeFix: false,
|
1077 |
-
opacity: false,
|
1078 |
-
refreshPositions: false,
|
1079 |
-
revert: false,
|
1080 |
-
revertDuration: 500,
|
1081 |
-
scope: "default",
|
1082 |
-
scroll: true,
|
1083 |
-
scrollSensitivity: 20,
|
1084 |
-
scrollSpeed: 20,
|
1085 |
-
snap: false,
|
1086 |
-
snapMode: "both",
|
1087 |
-
snapTolerance: 20,
|
1088 |
-
stack: false,
|
1089 |
-
zIndex: false
|
1090 |
-
},
|
1091 |
-
_create: function() {
|
1092 |
-
|
1093 |
-
if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
|
1094 |
-
this.element[0].style.position = 'relative';
|
1095 |
-
|
1096 |
-
(this.options.addClasses && this.element.addClass("ui-draggable"));
|
1097 |
-
(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
|
1098 |
|
1099 |
this._mouseInit();
|
1100 |
|
1101 |
},
|
1102 |
|
1103 |
-
|
1104 |
-
|
1105 |
-
this.element
|
1106 |
-
.removeData("draggable")
|
1107 |
-
.unbind(".draggable")
|
1108 |
-
.removeClass("ui-draggable"
|
1109 |
-
+ " ui-draggable-dragging"
|
1110 |
-
+ " ui-draggable-disabled");
|
1111 |
this._mouseDestroy();
|
1112 |
-
|
1113 |
-
return this;
|
1114 |
},
|
1115 |
|
1116 |
_mouseCapture: function(event) {
|
@@ -1118,26 +1044,26 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1118 |
var o = this.options;
|
1119 |
|
1120 |
// among others, prevent a drag on a resizable-handle
|
1121 |
-
if (this.helper || o.disabled || $(event.target).
|
1122 |
return false;
|
|
|
1123 |
|
1124 |
//Quit if we're not on a valid handle
|
1125 |
this.handle = this._getHandle(event);
|
1126 |
-
if (!this.handle)
|
1127 |
return false;
|
1128 |
-
|
1129 |
-
if ( o.iframeFix ) {
|
1130 |
-
$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
|
1131 |
-
$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
|
1132 |
-
.css({
|
1133 |
-
width: this.offsetWidth+"px", height: this.offsetHeight+"px",
|
1134 |
-
position: "absolute", opacity: "0.001", zIndex: 1000
|
1135 |
-
})
|
1136 |
-
.css($(this).offset())
|
1137 |
-
.appendTo("body");
|
1138 |
-
});
|
1139 |
}
|
1140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1141 |
return true;
|
1142 |
|
1143 |
},
|
@@ -1149,12 +1075,15 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1149 |
//Create and append the visible helper
|
1150 |
this.helper = this._createHelper(event);
|
1151 |
|
|
|
|
|
1152 |
//Cache the helper size
|
1153 |
this._cacheHelperProportions();
|
1154 |
|
1155 |
//If ddmanager is used for droppables, set the global draggable
|
1156 |
-
if($.ui.ddmanager)
|
1157 |
$.ui.ddmanager.current = this;
|
|
|
1158 |
|
1159 |
/*
|
1160 |
* - Position generation -
|
@@ -1189,12 +1118,13 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1189 |
this.originalPageX = event.pageX;
|
1190 |
this.originalPageY = event.pageY;
|
1191 |
|
1192 |
-
//Adjust the mouse offset relative to the helper if
|
1193 |
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
|
1194 |
|
1195 |
//Set a containment if given in the options
|
1196 |
-
if(o.containment)
|
1197 |
this._setContainment();
|
|
|
1198 |
|
1199 |
//Trigger event + callbacks
|
1200 |
if(this._trigger("start", event) === false) {
|
@@ -1206,15 +1136,18 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1206 |
this._cacheHelperProportions();
|
1207 |
|
1208 |
//Prepare the droppable offsets
|
1209 |
-
if ($.ui.ddmanager && !o.dropBehaviour)
|
1210 |
$.ui.ddmanager.prepareOffsets(this, event);
|
|
|
|
|
1211 |
|
1212 |
-
this.helper.addClass("ui-draggable-dragging");
|
1213 |
this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
|
1214 |
-
|
1215 |
//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
|
1216 |
-
if ( $.ui.ddmanager )
|
1217 |
-
|
|
|
|
|
1218 |
return true;
|
1219 |
},
|
1220 |
|
@@ -1227,16 +1160,22 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1227 |
//Call plugins and callbacks and use the resulting position if something is returned
|
1228 |
if (!noPropagation) {
|
1229 |
var ui = this._uiHash();
|
1230 |
-
if(this._trigger(
|
1231 |
this._mouseUp({});
|
1232 |
return false;
|
1233 |
}
|
1234 |
this.position = ui.position;
|
1235 |
}
|
1236 |
|
1237 |
-
if(!this.options.axis || this.options.axis
|
1238 |
-
|
1239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1240 |
|
1241 |
return false;
|
1242 |
},
|
@@ -1244,25 +1183,35 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1244 |
_mouseStop: function(event) {
|
1245 |
|
1246 |
//If we are using droppables, inform the manager about the drop
|
1247 |
-
var
|
1248 |
-
|
|
|
|
|
|
|
1249 |
dropped = $.ui.ddmanager.drop(this, event);
|
|
|
1250 |
|
1251 |
//if a drop comes from outside (a sortable)
|
1252 |
if(this.dropped) {
|
1253 |
dropped = this.dropped;
|
1254 |
this.dropped = false;
|
1255 |
}
|
1256 |
-
|
1257 |
-
//if the original element is
|
1258 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1259 |
return false;
|
|
|
1260 |
|
1261 |
-
if((this.options.revert
|
1262 |
-
var self = this;
|
1263 |
$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
|
1264 |
-
if(
|
1265 |
-
|
1266 |
}
|
1267 |
});
|
1268 |
} else {
|
@@ -1273,78 +1222,73 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1273 |
|
1274 |
return false;
|
1275 |
},
|
1276 |
-
|
1277 |
_mouseUp: function(event) {
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
|
1285 |
-
if( $.ui.ddmanager )
|
1286 |
-
|
|
|
|
|
1287 |
return $.ui.mouse.prototype._mouseUp.call(this, event);
|
1288 |
},
|
1289 |
-
|
1290 |
cancel: function() {
|
1291 |
-
|
1292 |
if(this.helper.is(".ui-draggable-dragging")) {
|
1293 |
this._mouseUp({});
|
1294 |
} else {
|
1295 |
this._clear();
|
1296 |
}
|
1297 |
-
|
1298 |
return this;
|
1299 |
-
|
1300 |
},
|
1301 |
|
1302 |
_getHandle: function(event) {
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
.find("*")
|
1307 |
-
.andSelf()
|
1308 |
-
.each(function() {
|
1309 |
-
if(this == event.target) handle = true;
|
1310 |
-
});
|
1311 |
-
|
1312 |
-
return handle;
|
1313 |
-
|
1314 |
},
|
1315 |
|
1316 |
_createHelper: function(event) {
|
1317 |
|
1318 |
-
var o = this.options
|
1319 |
-
|
1320 |
|
1321 |
-
if(!helper.parents(
|
1322 |
-
helper.appendTo((o.appendTo
|
|
|
1323 |
|
1324 |
-
if(helper[0]
|
1325 |
helper.css("position", "absolute");
|
|
|
1326 |
|
1327 |
return helper;
|
1328 |
|
1329 |
},
|
1330 |
|
1331 |
_adjustOffsetFromHelper: function(obj) {
|
1332 |
-
if (typeof obj
|
1333 |
-
obj = obj.split(
|
1334 |
}
|
1335 |
if ($.isArray(obj)) {
|
1336 |
obj = {left: +obj[0], top: +obj[1] || 0};
|
1337 |
}
|
1338 |
-
if (
|
1339 |
this.offset.click.left = obj.left + this.margins.left;
|
1340 |
}
|
1341 |
-
if (
|
1342 |
this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
|
1343 |
}
|
1344 |
-
if (
|
1345 |
this.offset.click.top = obj.top + this.margins.top;
|
1346 |
}
|
1347 |
-
if (
|
1348 |
this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
|
1349 |
}
|
1350 |
},
|
@@ -1359,14 +1303,17 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1359 |
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
|
1360 |
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
|
1361 |
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
|
1362 |
-
if(this.cssPosition
|
1363 |
po.left += this.scrollParent.scrollLeft();
|
1364 |
po.top += this.scrollParent.scrollTop();
|
1365 |
}
|
1366 |
|
1367 |
-
|
1368 |
-
|
|
|
|
|
1369 |
po = { top: 0, left: 0 };
|
|
|
1370 |
|
1371 |
return {
|
1372 |
top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
|
@@ -1377,7 +1324,7 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1377 |
|
1378 |
_getRelativeOffset: function() {
|
1379 |
|
1380 |
-
if(this.cssPosition
|
1381 |
var p = this.element.position();
|
1382 |
return {
|
1383 |
top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
|
@@ -1407,30 +1354,40 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1407 |
|
1408 |
_setContainment: function() {
|
1409 |
|
1410 |
-
var
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
o.containment
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1418 |
|
1419 |
-
if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
|
|
|
|
|
|
|
|
1424 |
|
1425 |
this.containment = [
|
1426 |
(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
|
1427 |
(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
|
1428 |
-
(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("
|
1429 |
-
(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("
|
1430 |
];
|
1431 |
this.relative_container = c;
|
1432 |
|
1433 |
-
} else if(o.containment.constructor
|
1434 |
this.containment = o.containment;
|
1435 |
}
|
1436 |
|
@@ -1438,22 +1395,25 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1438 |
|
1439 |
_convertPositionTo: function(d, pos) {
|
1440 |
|
1441 |
-
if(!pos)
|
1442 |
-
|
1443 |
-
|
|
|
|
|
|
|
1444 |
|
1445 |
return {
|
1446 |
top: (
|
1447 |
-
pos.top
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
),
|
1452 |
left: (
|
1453 |
-
pos.left // The absolute mouse position
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
)
|
1458 |
};
|
1459 |
|
@@ -1461,9 +1421,12 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1461 |
|
1462 |
_generatePosition: function(event) {
|
1463 |
|
1464 |
-
var
|
1465 |
-
|
1466 |
-
|
|
|
|
|
|
|
1467 |
|
1468 |
/*
|
1469 |
* - Position constraining -
|
@@ -1471,50 +1434,57 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1471 |
*/
|
1472 |
|
1473 |
if(this.originalPosition) { //If we are not dragging yet, we won't check for options
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
if(event.
|
1490 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1491 |
}
|
1492 |
|
1493 |
if(o.grid) {
|
1494 |
//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
|
1495 |
-
|
1496 |
-
pageY = containment ? (
|
1497 |
|
1498 |
-
|
1499 |
-
pageX = containment ? (
|
1500 |
}
|
1501 |
|
1502 |
}
|
1503 |
|
1504 |
return {
|
1505 |
top: (
|
1506 |
-
pageY
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
),
|
1512 |
left: (
|
1513 |
-
pageX
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
)
|
1519 |
};
|
1520 |
|
@@ -1522,8 +1492,9 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1522 |
|
1523 |
_clear: function() {
|
1524 |
this.helper.removeClass("ui-draggable-dragging");
|
1525 |
-
if(this.helper[0]
|
1526 |
-
|
|
|
1527 |
this.helper = null;
|
1528 |
this.cancelHelperRemoval = false;
|
1529 |
},
|
@@ -1533,13 +1504,16 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1533 |
_trigger: function(type, event, ui) {
|
1534 |
ui = ui || this._uiHash();
|
1535 |
$.ui.plugin.call(this, type, [event, ui]);
|
1536 |
-
|
|
|
|
|
|
|
1537 |
return $.Widget.prototype._trigger.call(this, type, event, ui);
|
1538 |
},
|
1539 |
|
1540 |
plugins: {},
|
1541 |
|
1542 |
-
_uiHash: function(
|
1543 |
return {
|
1544 |
helper: this.helper,
|
1545 |
position: this.position,
|
@@ -1550,18 +1524,14 @@ $.widget("ui.draggable", $.ui.mouse, {
|
|
1550 |
|
1551 |
});
|
1552 |
|
1553 |
-
$.extend($.ui.draggable, {
|
1554 |
-
version: "1.8.17"
|
1555 |
-
});
|
1556 |
-
|
1557 |
$.ui.plugin.add("draggable", "connectToSortable", {
|
1558 |
start: function(event, ui) {
|
1559 |
|
1560 |
-
var inst = $(this).data("draggable"), o = inst.options,
|
1561 |
uiSortable = $.extend({}, ui, { item: inst.element });
|
1562 |
inst.sortables = [];
|
1563 |
$(o.connectToSortable).each(function() {
|
1564 |
-
var sortable = $.data(this,
|
1565 |
if (sortable && !sortable.options.disabled) {
|
1566 |
inst.sortables.push({
|
1567 |
instance: sortable,
|
@@ -1576,7 +1546,7 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1576 |
stop: function(event, ui) {
|
1577 |
|
1578 |
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
|
1579 |
-
var inst = $(this).data("draggable"),
|
1580 |
uiSortable = $.extend({}, ui, { item: inst.element });
|
1581 |
|
1582 |
$.each(inst.sortables, function() {
|
@@ -1587,8 +1557,10 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1587 |
inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
|
1588 |
this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
|
1589 |
|
1590 |
-
//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert:
|
1591 |
-
if(this.shouldRevert)
|
|
|
|
|
1592 |
|
1593 |
//Trigger the stop of the sortable
|
1594 |
this.instance._mouseStop(event);
|
@@ -1596,8 +1568,9 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1596 |
this.instance.options.helper = this.instance.options._helper;
|
1597 |
|
1598 |
//If the helper has been the original item, restore properties in the sortable
|
1599 |
-
if(inst.options.helper
|
1600 |
-
this.instance.currentItem.css({ top:
|
|
|
1601 |
|
1602 |
} else {
|
1603 |
this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
|
@@ -1609,26 +1582,36 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1609 |
},
|
1610 |
drag: function(event, ui) {
|
1611 |
|
1612 |
-
var inst = $(this).data("draggable"),
|
1613 |
|
1614 |
-
|
1615 |
-
var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
|
1616 |
-
var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
|
1617 |
-
var itemHeight = o.height, itemWidth = o.width;
|
1618 |
-
var itemTop = o.top, itemLeft = o.left;
|
1619 |
|
1620 |
-
|
1621 |
-
|
1622 |
|
1623 |
-
$.each(inst.sortables, function(i) {
|
1624 |
-
|
1625 |
//Copy over some variables to allow calling the sortable's native _intersectsWith
|
1626 |
this.instance.positionAbs = inst.positionAbs;
|
1627 |
this.instance.helperProportions = inst.helperProportions;
|
1628 |
this.instance.offset.click = inst.offset.click;
|
1629 |
-
|
1630 |
if(this.instance._intersectsWith(this.instance.containerCache)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1631 |
|
|
|
|
|
1632 |
//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
|
1633 |
if(!this.instance.isOver) {
|
1634 |
|
@@ -1636,7 +1619,7 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1636 |
//Now we fake the start of dragging for the sortable instance,
|
1637 |
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
|
1638 |
//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)
|
1639 |
-
this.instance.currentItem = $(
|
1640 |
this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
|
1641 |
this.instance.options.helper = function() { return ui.helper[0]; };
|
1642 |
|
@@ -1659,7 +1642,9 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1659 |
}
|
1660 |
|
1661 |
//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
|
1662 |
-
if(this.instance.currentItem)
|
|
|
|
|
1663 |
|
1664 |
} else {
|
1665 |
|
@@ -1669,25 +1654,27 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1669 |
|
1670 |
this.instance.isOver = 0;
|
1671 |
this.instance.cancelHelperRemoval = true;
|
1672 |
-
|
1673 |
//Prevent reverting on this forced stop
|
1674 |
this.instance.options.revert = false;
|
1675 |
-
|
1676 |
// The out event needs to be triggered independently
|
1677 |
-
this.instance._trigger(
|
1678 |
-
|
1679 |
this.instance._mouseStop(event, true);
|
1680 |
this.instance.options.helper = this.instance.options._helper;
|
1681 |
|
1682 |
//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
|
1683 |
this.instance.currentItem.remove();
|
1684 |
-
if(this.instance.placeholder)
|
|
|
|
|
1685 |
|
1686 |
inst._trigger("fromSortable", event);
|
1687 |
inst.dropped = false; //draggable revert needs that
|
1688 |
}
|
1689 |
|
1690 |
-
}
|
1691 |
|
1692 |
});
|
1693 |
|
@@ -1695,212 +1682,257 @@ $.ui.plugin.add("draggable", "connectToSortable", {
|
|
1695 |
});
|
1696 |
|
1697 |
$.ui.plugin.add("draggable", "cursor", {
|
1698 |
-
start: function(
|
1699 |
-
var t = $(
|
1700 |
-
if (t.css("cursor"))
|
|
|
|
|
1701 |
t.css("cursor", o.cursor);
|
1702 |
},
|
1703 |
-
stop: function(
|
1704 |
-
var o = $(this).data(
|
1705 |
-
if (o._cursor)
|
|
|
|
|
1706 |
}
|
1707 |
});
|
1708 |
|
1709 |
$.ui.plugin.add("draggable", "opacity", {
|
1710 |
start: function(event, ui) {
|
1711 |
-
var t = $(ui.helper), o = $(this).data(
|
1712 |
-
if(t.css("opacity"))
|
1713 |
-
|
|
|
|
|
1714 |
},
|
1715 |
stop: function(event, ui) {
|
1716 |
-
var o = $(this).data(
|
1717 |
-
if(o._opacity)
|
|
|
|
|
1718 |
}
|
1719 |
});
|
1720 |
|
1721 |
$.ui.plugin.add("draggable", "scroll", {
|
1722 |
-
start: function(
|
1723 |
-
var i = $(this).data("draggable");
|
1724 |
-
if(i.scrollParent[0]
|
|
|
|
|
1725 |
},
|
1726 |
-
drag: function(event
|
1727 |
|
1728 |
-
var i = $(this).data("draggable"), o = i.options, scrolled = false;
|
1729 |
|
1730 |
-
if(i.scrollParent[0]
|
1731 |
|
1732 |
-
if(!o.axis || o.axis
|
1733 |
-
if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
|
1734 |
i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
|
1735 |
-
else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
|
1736 |
i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
|
|
|
1737 |
}
|
1738 |
|
1739 |
-
if(!o.axis || o.axis
|
1740 |
-
if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
|
1741 |
i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
|
1742 |
-
else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
|
1743 |
i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
|
|
|
1744 |
}
|
1745 |
|
1746 |
} else {
|
1747 |
|
1748 |
-
if(!o.axis || o.axis
|
1749 |
-
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
|
1750 |
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
1751 |
-
else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
|
1752 |
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
|
|
1753 |
}
|
1754 |
|
1755 |
-
if(!o.axis || o.axis
|
1756 |
-
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
|
1757 |
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
1758 |
-
else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
|
1759 |
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
|
|
1760 |
}
|
1761 |
|
1762 |
}
|
1763 |
|
1764 |
-
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
|
1765 |
$.ui.ddmanager.prepareOffsets(i, event);
|
|
|
1766 |
|
1767 |
}
|
1768 |
});
|
1769 |
|
1770 |
$.ui.plugin.add("draggable", "snap", {
|
1771 |
-
start: function(
|
|
|
|
|
|
|
1772 |
|
1773 |
-
var i = $(this).data("draggable"), o = i.options;
|
1774 |
i.snapElements = [];
|
1775 |
|
1776 |
-
$(o.snap.constructor
|
1777 |
-
var $t = $(this)
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
|
|
|
|
|
|
1783 |
});
|
1784 |
|
1785 |
},
|
1786 |
drag: function(event, ui) {
|
1787 |
|
1788 |
-
var
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
|
|
1792 |
y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
|
1793 |
|
1794 |
-
for (
|
1795 |
|
1796 |
-
|
1797 |
-
|
|
|
|
|
1798 |
|
1799 |
//Yes, I know, this is insane ;)
|
1800 |
if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
|
1801 |
-
if(inst.snapElements[i].snapping)
|
|
|
|
|
1802 |
inst.snapElements[i].snapping = false;
|
1803 |
continue;
|
1804 |
}
|
1805 |
|
1806 |
-
if(o.snapMode
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
|
1811 |
-
if(ts)
|
1812 |
-
|
1813 |
-
|
1814 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1815 |
}
|
1816 |
|
1817 |
-
|
1818 |
|
1819 |
-
if(o.snapMode
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
if(ts)
|
1825 |
-
|
1826 |
-
|
1827 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1828 |
}
|
1829 |
|
1830 |
-
if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
|
1831 |
(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
|
|
|
1832 |
inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
|
1833 |
|
1834 |
-
}
|
1835 |
|
1836 |
}
|
1837 |
});
|
1838 |
|
1839 |
$.ui.plugin.add("draggable", "stack", {
|
1840 |
-
start: function(
|
1841 |
-
|
1842 |
-
|
|
|
|
|
|
|
1843 |
|
1844 |
-
var group = $.makeArray($(o.stack)).sort(function(a,b) {
|
1845 |
-
return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
|
1846 |
-
});
|
1847 |
if (!group.length) { return; }
|
1848 |
-
|
1849 |
-
|
1850 |
$(group).each(function(i) {
|
1851 |
-
this.
|
1852 |
});
|
1853 |
-
|
1854 |
-
this[0].style.zIndex = min + group.length;
|
1855 |
-
|
1856 |
}
|
1857 |
});
|
1858 |
|
1859 |
$.ui.plugin.add("draggable", "zIndex", {
|
1860 |
start: function(event, ui) {
|
1861 |
-
var t = $(ui.helper), o = $(this).data("draggable").options;
|
1862 |
-
if(t.css("zIndex"))
|
1863 |
-
|
|
|
|
|
1864 |
},
|
1865 |
stop: function(event, ui) {
|
1866 |
-
var o = $(this).data("draggable").options;
|
1867 |
-
if(o._zIndex)
|
|
|
|
|
1868 |
}
|
1869 |
});
|
1870 |
|
1871 |
})(jQuery);
|
1872 |
-
|
1873 |
-
* jQuery UI Droppable 1.8.17
|
1874 |
-
*
|
1875 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
1876 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
1877 |
-
* http://jquery.org/license
|
1878 |
-
*
|
1879 |
-
* http://docs.jquery.com/UI/Droppables
|
1880 |
-
*
|
1881 |
-
* Depends:
|
1882 |
-
* jquery.ui.core.js
|
1883 |
-
* jquery.ui.widget.js
|
1884 |
-
* jquery.ui.mouse.js
|
1885 |
-
* jquery.ui.draggable.js
|
1886 |
-
*/
|
1887 |
(function( $, undefined ) {
|
1888 |
|
|
|
|
|
|
|
|
|
1889 |
$.widget("ui.droppable", {
|
|
|
1890 |
widgetEventPrefix: "drop",
|
1891 |
options: {
|
1892 |
-
accept:
|
1893 |
activeClass: false,
|
1894 |
addClasses: true,
|
1895 |
greedy: false,
|
1896 |
hoverClass: false,
|
1897 |
-
scope:
|
1898 |
-
tolerance:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1899 |
},
|
1900 |
_create: function() {
|
1901 |
|
1902 |
-
var o = this.options,
|
1903 |
-
|
|
|
|
|
|
|
1904 |
|
1905 |
this.accept = $.isFunction(accept) ? accept : function(d) {
|
1906 |
return d.is(accept);
|
@@ -1917,23 +1949,22 @@ $.widget("ui.droppable", {
|
|
1917 |
|
1918 |
},
|
1919 |
|
1920 |
-
|
1921 |
-
var
|
1922 |
-
|
1923 |
-
if ( drop[i] == this )
|
1924 |
-
drop.splice(i, 1);
|
1925 |
|
1926 |
-
|
1927 |
-
|
1928 |
-
|
1929 |
-
|
|
|
1930 |
|
1931 |
-
|
1932 |
},
|
1933 |
|
1934 |
_setOption: function(key, value) {
|
1935 |
|
1936 |
-
if(key
|
1937 |
this.accept = $.isFunction(value) ? value : function(d) {
|
1938 |
return d.is(value);
|
1939 |
};
|
@@ -1943,24 +1974,38 @@ $.widget("ui.droppable", {
|
|
1943 |
|
1944 |
_activate: function(event) {
|
1945 |
var draggable = $.ui.ddmanager.current;
|
1946 |
-
if(this.options.activeClass)
|
1947 |
-
|
|
|
|
|
|
|
|
|
1948 |
},
|
1949 |
|
1950 |
_deactivate: function(event) {
|
1951 |
var draggable = $.ui.ddmanager.current;
|
1952 |
-
if(this.options.activeClass)
|
1953 |
-
|
|
|
|
|
|
|
|
|
1954 |
},
|
1955 |
|
1956 |
_over: function(event) {
|
1957 |
|
1958 |
var draggable = $.ui.ddmanager.current;
|
1959 |
-
|
|
|
|
|
|
|
|
|
1960 |
|
1961 |
if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
1962 |
-
if(this.options.hoverClass)
|
1963 |
-
|
|
|
|
|
1964 |
}
|
1965 |
|
1966 |
},
|
@@ -1968,37 +2013,53 @@ $.widget("ui.droppable", {
|
|
1968 |
_out: function(event) {
|
1969 |
|
1970 |
var draggable = $.ui.ddmanager.current;
|
1971 |
-
|
|
|
|
|
|
|
|
|
1972 |
|
1973 |
if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
1974 |
-
if(this.options.hoverClass)
|
1975 |
-
|
|
|
|
|
1976 |
}
|
1977 |
|
1978 |
},
|
1979 |
|
1980 |
_drop: function(event,custom) {
|
1981 |
|
1982 |
-
var draggable = custom || $.ui.ddmanager.current
|
1983 |
-
|
|
|
|
|
|
|
|
|
|
|
1984 |
|
1985 |
-
|
1986 |
-
|
1987 |
-
var inst = $.data(this, 'droppable');
|
1988 |
if(
|
1989 |
-
inst.options.greedy
|
1990 |
-
|
1991 |
-
|
1992 |
-
|
1993 |
-
|
1994 |
) { childrenIntersection = true; return false; }
|
1995 |
});
|
1996 |
-
if(childrenIntersection)
|
|
|
|
|
1997 |
|
1998 |
if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
1999 |
-
if(this.options.activeClass)
|
2000 |
-
|
2001 |
-
|
|
|
|
|
|
|
|
|
2002 |
return this.element;
|
2003 |
}
|
2004 |
|
@@ -2017,50 +2078,42 @@ $.widget("ui.droppable", {
|
|
2017 |
|
2018 |
});
|
2019 |
|
2020 |
-
$.extend($.ui.droppable, {
|
2021 |
-
version: "1.8.17"
|
2022 |
-
});
|
2023 |
-
|
2024 |
$.ui.intersect = function(draggable, droppable, toleranceMode) {
|
2025 |
|
2026 |
-
if (!droppable.offset)
|
|
|
|
|
2027 |
|
2028 |
-
var
|
2029 |
-
|
2030 |
-
|
|
|
2031 |
t = droppable.offset.top, b = t + droppable.proportions.height;
|
2032 |
|
2033 |
switch (toleranceMode) {
|
2034 |
-
case
|
2035 |
-
return (l <= x1 && x2 <= r
|
2036 |
-
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
-
|
2043 |
-
|
2044 |
-
|
2045 |
-
|
2046 |
-
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
|
2047 |
-
isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
|
2048 |
-
return isOver;
|
2049 |
-
break;
|
2050 |
-
case 'touch':
|
2051 |
return (
|
2052 |
-
|
2053 |
-
|
2054 |
-
|
2055 |
-
|
2056 |
-
|
2057 |
-
|
2058 |
-
|
2059 |
-
|
2060 |
-
break;
|
2061 |
default:
|
2062 |
return false;
|
2063 |
-
break;
|
2064 |
}
|
2065 |
|
2066 |
};
|
@@ -2070,20 +2123,38 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) {
|
|
2070 |
*/
|
2071 |
$.ui.ddmanager = {
|
2072 |
current: null,
|
2073 |
-
droppables: {
|
2074 |
prepareOffsets: function(t, event) {
|
2075 |
|
2076 |
-
var
|
2077 |
-
|
2078 |
-
|
|
|
|
|
|
|
2079 |
|
2080 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2081 |
|
2082 |
-
|
2083 |
-
|
2084 |
-
|
|
|
2085 |
|
2086 |
-
|
|
|
|
|
|
|
2087 |
|
2088 |
m[i].offset = m[i].element.offset();
|
2089 |
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
|
@@ -2094,14 +2165,19 @@ $.ui.ddmanager = {
|
|
2094 |
drop: function(draggable, event) {
|
2095 |
|
2096 |
var dropped = false;
|
2097 |
-
|
|
|
2098 |
|
2099 |
-
if(!this.options)
|
2100 |
-
|
|
|
|
|
2101 |
dropped = this._drop.call(this, event) || dropped;
|
|
|
2102 |
|
2103 |
if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
2104 |
-
this.isout =
|
|
|
2105 |
this._deactivate.call(this, event);
|
2106 |
}
|
2107 |
|
@@ -2111,77 +2187,89 @@ $.ui.ddmanager = {
|
|
2111 |
},
|
2112 |
dragStart: function( draggable, event ) {
|
2113 |
//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
|
2114 |
-
draggable.element.
|
2115 |
-
if( !draggable.options.refreshPositions )
|
|
|
|
|
2116 |
});
|
2117 |
},
|
2118 |
drag: function(draggable, event) {
|
2119 |
|
2120 |
//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
|
2121 |
-
if(draggable.options.refreshPositions)
|
|
|
|
|
2122 |
|
2123 |
//Run through all droppables and check their positions based on specific tolerance options
|
2124 |
$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
|
2125 |
|
2126 |
-
if(this.options.disabled || this.greedyChild || !this.visible)
|
2127 |
-
|
|
|
2128 |
|
2129 |
-
var
|
2130 |
-
|
|
|
|
|
|
|
|
|
2131 |
|
2132 |
-
var parentInstance;
|
2133 |
if (this.options.greedy) {
|
2134 |
-
|
|
|
|
|
|
|
|
|
|
|
2135 |
if (parent.length) {
|
2136 |
-
parentInstance = $.data(parent[0],
|
2137 |
-
parentInstance.greedyChild = (c
|
2138 |
}
|
2139 |
}
|
2140 |
|
2141 |
// we just moved into a greedy child
|
2142 |
-
if (parentInstance && c
|
2143 |
-
parentInstance
|
2144 |
-
parentInstance
|
2145 |
parentInstance._out.call(parentInstance, event);
|
2146 |
}
|
2147 |
|
2148 |
-
this[c] =
|
2149 |
-
this[c
|
|
|
2150 |
|
2151 |
// we just moved out of a greedy child
|
2152 |
-
if (parentInstance && c
|
2153 |
-
parentInstance
|
2154 |
-
parentInstance
|
2155 |
parentInstance._over.call(parentInstance, event);
|
2156 |
}
|
2157 |
});
|
2158 |
|
2159 |
},
|
2160 |
dragStop: function( draggable, event ) {
|
2161 |
-
draggable.element.
|
2162 |
//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
|
2163 |
-
if( !draggable.options.refreshPositions )
|
|
|
|
|
2164 |
}
|
2165 |
};
|
2166 |
|
2167 |
})(jQuery);
|
2168 |
-
|
2169 |
-
* jQuery UI Resizable 1.8.17
|
2170 |
-
*
|
2171 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
2172 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
2173 |
-
* http://jquery.org/license
|
2174 |
-
*
|
2175 |
-
* http://docs.jquery.com/UI/Resizables
|
2176 |
-
*
|
2177 |
-
* Depends:
|
2178 |
-
* jquery.ui.core.js
|
2179 |
-
* jquery.ui.mouse.js
|
2180 |
-
* jquery.ui.widget.js
|
2181 |
-
*/
|
2182 |
(function( $, undefined ) {
|
2183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2184 |
$.widget("ui.resizable", $.ui.mouse, {
|
|
|
2185 |
widgetEventPrefix: "resize",
|
2186 |
options: {
|
2187 |
alsoResize: false,
|
@@ -2199,11 +2287,19 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2199 |
maxWidth: null,
|
2200 |
minHeight: 10,
|
2201 |
minWidth: 10,
|
2202 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2203 |
},
|
2204 |
_create: function() {
|
2205 |
|
2206 |
-
var
|
|
|
|
|
2207 |
this.element.addClass("ui-resizable");
|
2208 |
|
2209 |
$.extend(this, {
|
@@ -2211,30 +2307,26 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2211 |
aspectRatio: o.aspectRatio,
|
2212 |
originalElement: this.element,
|
2213 |
_proportionallyResizeElements: [],
|
2214 |
-
_helper: o.helper || o.ghost || o.animate ? o.helper ||
|
2215 |
});
|
2216 |
|
2217 |
//Wrap the element if it cannot hold child nodes
|
2218 |
if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
|
2219 |
|
2220 |
-
//Opera fix for relative positioning
|
2221 |
-
if (/relative/.test(this.element.css('position')) && $.browser.opera)
|
2222 |
-
this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
|
2223 |
-
|
2224 |
//Create a wrapper element and set the wrapper to the new current internal element
|
2225 |
this.element.wrap(
|
2226 |
-
$(
|
2227 |
-
position: this.element.css(
|
2228 |
width: this.element.outerWidth(),
|
2229 |
height: this.element.outerHeight(),
|
2230 |
-
top: this.element.css(
|
2231 |
-
left: this.element.css(
|
2232 |
})
|
2233 |
);
|
2234 |
|
2235 |
//Overwrite the original this.element
|
2236 |
this.element = this.element.parent().data(
|
2237 |
-
"resizable", this.element.data(
|
2238 |
);
|
2239 |
|
2240 |
this.elementIsWrapper = true;
|
@@ -2244,42 +2336,46 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2244 |
this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
|
2245 |
|
2246 |
//Prevent Safari textarea resize
|
2247 |
-
this.originalResizeStyle = this.originalElement.css(
|
2248 |
-
this.originalElement.css(
|
2249 |
|
2250 |
//Push the actual element to our proportionallyResize internal array
|
2251 |
-
this._proportionallyResizeElements.push(this.originalElement.css({ position:
|
2252 |
|
2253 |
// avoid IE jump (hard set the margin)
|
2254 |
-
this.originalElement.css({ margin: this.originalElement.css(
|
2255 |
|
2256 |
// fix handlers offset
|
2257 |
this._proportionallyResize();
|
2258 |
|
2259 |
}
|
2260 |
|
2261 |
-
this.handles = o.handles || (!$(
|
2262 |
-
if(this.handles.constructor
|
|
|
|
|
|
|
|
|
2263 |
|
2264 |
-
|
2265 |
-
|
2266 |
|
2267 |
-
for(
|
2268 |
|
2269 |
-
|
2270 |
-
|
|
|
2271 |
|
2272 |
-
//
|
2273 |
-
|
2274 |
-
if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
|
2275 |
|
2276 |
//TODO : What's going on here?
|
2277 |
-
if (
|
2278 |
-
axis.addClass(
|
2279 |
-
}
|
2280 |
|
2281 |
//Insert into internal handles object and append to element
|
2282 |
-
this.handles[handle] =
|
2283 |
this.element.append(axis);
|
2284 |
}
|
2285 |
|
@@ -2287,26 +2383,29 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2287 |
|
2288 |
this._renderAxis = function(target) {
|
2289 |
|
|
|
|
|
2290 |
target = target || this.element;
|
2291 |
|
2292 |
-
for(
|
2293 |
|
2294 |
-
if(this.handles[i].constructor
|
2295 |
this.handles[i] = $(this.handles[i], this.element).show();
|
|
|
2296 |
|
2297 |
//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
|
2298 |
if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
|
2299 |
|
2300 |
-
|
2301 |
|
2302 |
//Checking the correct pad and border
|
2303 |
padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
|
2304 |
|
2305 |
//The padding type i have to apply...
|
2306 |
-
|
2307 |
-
/ne|nw|n/.test(i) ?
|
2308 |
-
/se|sw|s/.test(i) ?
|
2309 |
-
/^e$/.test(i) ?
|
2310 |
|
2311 |
target.css(padPos, padWrapper);
|
2312 |
|
@@ -2315,25 +2414,26 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2315 |
}
|
2316 |
|
2317 |
//TODO: What's that good for? There's not anything to be executed left
|
2318 |
-
if(!$(this.handles[i]).length)
|
2319 |
continue;
|
2320 |
-
|
2321 |
}
|
2322 |
};
|
2323 |
|
2324 |
//TODO: make renderAxis a prototype function
|
2325 |
this._renderAxis(this.element);
|
2326 |
|
2327 |
-
this._handles = $(
|
2328 |
.disableSelection();
|
2329 |
|
2330 |
//Matching axis name
|
2331 |
this._handles.mouseover(function() {
|
2332 |
-
if (!
|
2333 |
-
if (this.className)
|
2334 |
-
|
|
|
2335 |
//Axis, default = se
|
2336 |
-
|
2337 |
}
|
2338 |
});
|
2339 |
|
@@ -2342,16 +2442,20 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2342 |
this._handles.hide();
|
2343 |
$(this.element)
|
2344 |
.addClass("ui-resizable-autohide")
|
2345 |
-
.
|
2346 |
-
if (o.disabled)
|
|
|
|
|
2347 |
$(this).removeClass("ui-resizable-autohide");
|
2348 |
-
|
2349 |
-
}
|
2350 |
-
function(){
|
2351 |
-
if (o.disabled)
|
2352 |
-
|
|
|
|
|
2353 |
$(this).addClass("ui-resizable-autohide");
|
2354 |
-
|
2355 |
}
|
2356 |
});
|
2357 |
}
|
@@ -2361,66 +2465,70 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2361 |
|
2362 |
},
|
2363 |
|
2364 |
-
|
2365 |
|
2366 |
this._mouseDestroy();
|
2367 |
|
2368 |
-
var
|
2369 |
-
|
2370 |
-
|
2371 |
-
|
|
|
2372 |
|
2373 |
//TODO: Unwrap at same DOM position
|
2374 |
if (this.elementIsWrapper) {
|
2375 |
_destroy(this.element);
|
2376 |
-
|
2377 |
-
|
2378 |
-
|
2379 |
-
|
2380 |
-
|
2381 |
-
|
2382 |
-
|
2383 |
-
|
2384 |
-
|
2385 |
-
|
2386 |
-
|
2387 |
-
|
2388 |
-
this.originalElement.css('resize', this.originalResizeStyle);
|
2389 |
_destroy(this.originalElement);
|
2390 |
|
2391 |
return this;
|
2392 |
},
|
2393 |
|
2394 |
_mouseCapture: function(event) {
|
2395 |
-
var handle
|
2396 |
-
|
2397 |
-
|
2398 |
-
|
|
|
|
|
|
|
2399 |
}
|
2400 |
}
|
2401 |
|
2402 |
-
return !this.options.disabled &&
|
2403 |
},
|
2404 |
|
2405 |
_mouseStart: function(event) {
|
2406 |
|
2407 |
-
var
|
|
|
|
|
|
|
2408 |
|
2409 |
this.resizing = true;
|
2410 |
-
this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
|
2411 |
|
2412 |
// bugfix for http://dev.jquery.com/ticket/1749
|
2413 |
-
if (
|
2414 |
-
el.css({ position:
|
|
|
|
|
2415 |
}
|
2416 |
|
2417 |
-
//Opera fixing relative position
|
2418 |
-
if ($.browser.opera && (/relative/).test(el.css('position')))
|
2419 |
-
el.css({ position: 'relative', top: 'auto', left: 'auto' });
|
2420 |
-
|
2421 |
this._renderProxy();
|
2422 |
|
2423 |
-
|
|
|
2424 |
|
2425 |
if (o.containment) {
|
2426 |
curleft += $(o.containment).scrollLeft() || 0;
|
@@ -2437,10 +2545,10 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2437 |
this.originalMousePosition = { left: event.pageX, top: event.pageY };
|
2438 |
|
2439 |
//Aspect Ratio
|
2440 |
-
this.aspectRatio = (typeof o.aspectRatio
|
2441 |
|
2442 |
-
|
2443 |
-
|
2444 |
|
2445 |
el.addClass("ui-resizable-resizing");
|
2446 |
this._propagate("start", event);
|
@@ -2450,38 +2558,60 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2450 |
_mouseDrag: function(event) {
|
2451 |
|
2452 |
//Increase performance, avoid regex
|
2453 |
-
var
|
2454 |
-
|
2455 |
-
|
2456 |
-
|
2457 |
-
|
2458 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2459 |
|
2460 |
// Calculate the attrs that will be change
|
2461 |
-
|
2462 |
|
2463 |
// Put this in the mouseDrag handler since the user can start pressing shift while resizing
|
2464 |
this._updateVirtualBoundaries(event.shiftKey);
|
2465 |
-
if (this._aspectRatio || event.shiftKey)
|
2466 |
data = this._updateRatio(data, event);
|
|
|
2467 |
|
2468 |
data = this._respectSize(data, event);
|
2469 |
|
|
|
|
|
2470 |
// plugins callbacks need to be called first
|
2471 |
this._propagate("resize", event);
|
2472 |
|
2473 |
-
|
2474 |
-
|
2475 |
-
|
2476 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2477 |
|
2478 |
-
if (!this._helper && this._proportionallyResizeElements.length)
|
2479 |
this._proportionallyResize();
|
|
|
2480 |
|
2481 |
-
|
2482 |
-
|
2483 |
-
|
2484 |
-
|
2485 |
|
2486 |
return false;
|
2487 |
},
|
@@ -2489,84 +2619,114 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2489 |
_mouseStop: function(event) {
|
2490 |
|
2491 |
this.resizing = false;
|
2492 |
-
var
|
|
|
2493 |
|
2494 |
if(this._helper) {
|
2495 |
-
var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
|
2496 |
-
soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
|
2497 |
-
soffsetw = ista ? 0 : self.sizeDiff.width;
|
2498 |
|
2499 |
-
|
2500 |
-
|
2501 |
-
|
|
|
|
|
|
|
|
|
|
|
2502 |
|
2503 |
-
if (!o.animate)
|
2504 |
this.element.css($.extend(s, { top: top, left: left }));
|
|
|
2505 |
|
2506 |
-
|
2507 |
-
|
2508 |
|
2509 |
-
if (this._helper && !o.animate)
|
|
|
|
|
2510 |
}
|
2511 |
|
2512 |
-
$(
|
2513 |
|
2514 |
this.element.removeClass("ui-resizable-resizing");
|
2515 |
|
2516 |
this._propagate("stop", event);
|
2517 |
|
2518 |
-
if (this._helper)
|
|
|
|
|
|
|
2519 |
return false;
|
2520 |
|
2521 |
},
|
2522 |
|
2523 |
-
|
2524 |
-
|
|
|
2525 |
|
2526 |
-
|
2527 |
-
|
2528 |
-
|
2529 |
-
|
2530 |
-
|
2531 |
-
|
2532 |
|
2533 |
-
|
2534 |
-
|
2535 |
-
|
2536 |
-
|
2537 |
-
|
2538 |
-
|
2539 |
-
|
2540 |
|
2541 |
-
|
2542 |
-
|
2543 |
-
|
2544 |
-
|
2545 |
-
|
2546 |
-
|
2547 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2548 |
|
2549 |
_updateCache: function(data) {
|
2550 |
-
var o = this.options;
|
2551 |
this.offset = this.helper.offset();
|
2552 |
-
if (isNumber(data.left))
|
2553 |
-
|
2554 |
-
|
2555 |
-
if (isNumber(data.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2556 |
},
|
2557 |
|
2558 |
-
_updateRatio: function(data
|
2559 |
|
2560 |
-
var
|
|
|
|
|
2561 |
|
2562 |
-
if (isNumber(data.height))
|
2563 |
-
|
|
|
|
|
|
|
2564 |
|
2565 |
-
if (a
|
2566 |
data.left = cpos.left + (csize.width - data.width);
|
2567 |
data.top = null;
|
2568 |
}
|
2569 |
-
if (a
|
2570 |
data.top = cpos.top + (csize.height - data.height);
|
2571 |
data.left = cpos.left + (csize.width - data.width);
|
2572 |
}
|
@@ -2574,62 +2734,80 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2574 |
return data;
|
2575 |
},
|
2576 |
|
2577 |
-
_respectSize: function(data
|
2578 |
|
2579 |
-
var
|
2580 |
-
|
2581 |
-
|
2582 |
-
|
2583 |
-
|
2584 |
-
|
2585 |
-
|
2586 |
-
if (
|
2587 |
-
|
2588 |
-
|
2589 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2590 |
|
2591 |
-
if (isminw && cw)
|
2592 |
-
|
2593 |
-
|
2594 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2595 |
|
2596 |
// fixing jump error on top/left - bug #2330
|
2597 |
-
|
2598 |
-
|
2599 |
-
else if (
|
|
|
|
|
2600 |
|
2601 |
return data;
|
2602 |
},
|
2603 |
|
2604 |
_proportionallyResize: function() {
|
2605 |
|
2606 |
-
|
2607 |
-
|
2608 |
-
|
|
|
|
|
|
|
2609 |
|
2610 |
-
for (
|
2611 |
|
2612 |
-
|
2613 |
|
2614 |
if (!this.borderDif) {
|
2615 |
-
|
2616 |
-
|
|
|
2617 |
|
2618 |
-
|
2619 |
-
|
2620 |
-
|
2621 |
-
});
|
2622 |
}
|
2623 |
|
2624 |
-
if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
|
2625 |
-
continue;
|
2626 |
-
|
2627 |
prel.css({
|
2628 |
height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
|
2629 |
width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
|
2630 |
});
|
2631 |
|
2632 |
-
}
|
2633 |
|
2634 |
},
|
2635 |
|
@@ -2640,18 +2818,14 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2640 |
|
2641 |
if(this._helper) {
|
2642 |
|
2643 |
-
this.helper = this.helper || $(
|
2644 |
-
|
2645 |
-
// fix ie6 offset TODO: This seems broken
|
2646 |
-
var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
|
2647 |
-
pxyoffset = ( ie6 ? 2 : -1 );
|
2648 |
|
2649 |
this.helper.addClass(this._helper).css({
|
2650 |
-
width: this.element.outerWidth()
|
2651 |
-
height: this.element.outerHeight()
|
2652 |
-
position:
|
2653 |
-
left: this.elementOffset.left
|
2654 |
-
top: this.elementOffset.top
|
2655 |
zIndex: ++o.zIndex //TODO: Don't modify option
|
2656 |
});
|
2657 |
|
@@ -2666,15 +2840,15 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2666 |
},
|
2667 |
|
2668 |
_change: {
|
2669 |
-
e: function(event, dx
|
2670 |
return { width: this.originalSize.width + dx };
|
2671 |
},
|
2672 |
-
w: function(event, dx
|
2673 |
-
var
|
2674 |
return { left: sp.left + dx, width: cs.width - dx };
|
2675 |
},
|
2676 |
n: function(event, dx, dy) {
|
2677 |
-
var
|
2678 |
return { top: sp.top + dy, height: cs.height - dy };
|
2679 |
},
|
2680 |
s: function(event, dx, dy) {
|
@@ -2696,7 +2870,7 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2696 |
|
2697 |
_propagate: function(n, event) {
|
2698 |
$.ui.plugin.call(this, n, [event, this.ui()]);
|
2699 |
-
(n
|
2700 |
},
|
2701 |
|
2702 |
plugins: {},
|
@@ -2715,129 +2889,43 @@ $.widget("ui.resizable", $.ui.mouse, {
|
|
2715 |
|
2716 |
});
|
2717 |
|
2718 |
-
$.extend($.ui.resizable, {
|
2719 |
-
version: "1.8.17"
|
2720 |
-
});
|
2721 |
-
|
2722 |
/*
|
2723 |
* Resizable Extensions
|
2724 |
*/
|
2725 |
|
2726 |
-
$.ui.plugin.add("resizable", "
|
2727 |
-
|
2728 |
-
start: function (event, ui) {
|
2729 |
-
var self = $(this).data("resizable"), o = self.options;
|
2730 |
-
|
2731 |
-
var _store = function (exp) {
|
2732 |
-
$(exp).each(function() {
|
2733 |
-
var el = $(this);
|
2734 |
-
el.data("resizable-alsoresize", {
|
2735 |
-
width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
|
2736 |
-
left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
|
2737 |
-
position: el.css('position') // to reset Opera on stop()
|
2738 |
-
});
|
2739 |
-
});
|
2740 |
-
};
|
2741 |
|
2742 |
-
|
2743 |
-
|
2744 |
-
|
2745 |
-
|
2746 |
-
|
2747 |
-
|
2748 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2749 |
|
2750 |
-
|
2751 |
-
|
|
|
|
|
|
|
|
|
2752 |
|
2753 |
-
|
2754 |
-
|
2755 |
-
|
2756 |
-
},
|
2757 |
|
2758 |
-
|
2759 |
-
|
2760 |
-
|
2761 |
-
css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
|
2762 |
-
|
2763 |
-
$.each(css, function (i, prop) {
|
2764 |
-
var sum = (start[prop]||0) + (delta[prop]||0);
|
2765 |
-
if (sum && sum >= 0)
|
2766 |
-
style[prop] = sum || null;
|
2767 |
-
});
|
2768 |
-
|
2769 |
-
// Opera fixing relative position
|
2770 |
-
if ($.browser.opera && /relative/.test(el.css('position'))) {
|
2771 |
-
self._revertToRelativePosition = true;
|
2772 |
-
el.css({ position: 'absolute', top: 'auto', left: 'auto' });
|
2773 |
-
}
|
2774 |
-
|
2775 |
-
el.css(style);
|
2776 |
-
});
|
2777 |
-
};
|
2778 |
-
|
2779 |
-
if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
|
2780 |
-
$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
|
2781 |
-
}else{
|
2782 |
-
_alsoResize(o.alsoResize);
|
2783 |
-
}
|
2784 |
-
},
|
2785 |
-
|
2786 |
-
stop: function (event, ui) {
|
2787 |
-
var self = $(this).data("resizable"), o = self.options;
|
2788 |
-
|
2789 |
-
var _reset = function (exp) {
|
2790 |
-
$(exp).each(function() {
|
2791 |
-
var el = $(this);
|
2792 |
-
// reset position for Opera - no need to verify it was changed
|
2793 |
-
el.css({ position: el.data("resizable-alsoresize").position });
|
2794 |
-
});
|
2795 |
-
};
|
2796 |
-
|
2797 |
-
if (self._revertToRelativePosition) {
|
2798 |
-
self._revertToRelativePosition = false;
|
2799 |
-
if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
|
2800 |
-
$.each(o.alsoResize, function (exp) { _reset(exp); });
|
2801 |
-
}else{
|
2802 |
-
_reset(o.alsoResize);
|
2803 |
-
}
|
2804 |
-
}
|
2805 |
-
|
2806 |
-
$(this).removeData("resizable-alsoresize");
|
2807 |
-
}
|
2808 |
-
});
|
2809 |
-
|
2810 |
-
$.ui.plugin.add("resizable", "animate", {
|
2811 |
-
|
2812 |
-
stop: function(event, ui) {
|
2813 |
-
var self = $(this).data("resizable"), o = self.options;
|
2814 |
-
|
2815 |
-
var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
|
2816 |
-
soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
|
2817 |
-
soffsetw = ista ? 0 : self.sizeDiff.width;
|
2818 |
-
|
2819 |
-
var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
|
2820 |
-
left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
|
2821 |
-
top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
|
2822 |
-
|
2823 |
-
self.element.animate(
|
2824 |
-
$.extend(style, top && left ? { top: top, left: left } : {}), {
|
2825 |
-
duration: o.animateDuration,
|
2826 |
-
easing: o.animateEasing,
|
2827 |
-
step: function() {
|
2828 |
-
|
2829 |
-
var data = {
|
2830 |
-
width: parseInt(self.element.css('width'), 10),
|
2831 |
-
height: parseInt(self.element.css('height'), 10),
|
2832 |
-
top: parseInt(self.element.css('top'), 10),
|
2833 |
-
left: parseInt(self.element.css('left'), 10)
|
2834 |
-
};
|
2835 |
-
|
2836 |
-
if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
|
2837 |
-
|
2838 |
-
// propagating resize, and updating values for each animation step
|
2839 |
-
self._updateCache(data);
|
2840 |
-
self._propagate("resize", event);
|
2841 |
|
2842 |
}
|
2843 |
}
|
@@ -2848,18 +2936,25 @@ $.ui.plugin.add("resizable", "animate", {
|
|
2848 |
|
2849 |
$.ui.plugin.add("resizable", "containment", {
|
2850 |
|
2851 |
-
start: function(
|
2852 |
-
var
|
2853 |
-
|
2854 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2855 |
|
2856 |
-
|
2857 |
|
2858 |
-
if (/document/.test(oc) || oc
|
2859 |
-
|
2860 |
-
|
2861 |
|
2862 |
-
|
2863 |
element: $(document), left: 0, top: 0,
|
2864 |
width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
|
2865 |
};
|
@@ -2867,185 +2962,290 @@ $.ui.plugin.add("resizable", "containment", {
|
|
2867 |
|
2868 |
// i'm a node, so compute top, left, right, bottom
|
2869 |
else {
|
2870 |
-
|
|
|
2871 |
$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
|
2872 |
|
2873 |
-
|
2874 |
-
|
2875 |
-
|
2876 |
|
2877 |
-
|
2878 |
-
|
|
|
|
|
|
|
2879 |
|
2880 |
-
|
2881 |
element: ce, left: co.left, top: co.top, width: width, height: height
|
2882 |
};
|
2883 |
}
|
2884 |
},
|
2885 |
|
2886 |
-
resize: function(event
|
2887 |
-
var
|
2888 |
-
|
2889 |
-
|
|
|
|
|
|
|
2890 |
|
2891 |
-
if (ce[0]
|
|
|
|
|
2892 |
|
2893 |
-
if (cp.left < (
|
2894 |
-
|
2895 |
-
if (pRatio)
|
2896 |
-
|
|
|
|
|
2897 |
}
|
2898 |
|
2899 |
-
if (cp.top < (
|
2900 |
-
|
2901 |
-
if (pRatio)
|
2902 |
-
|
|
|
|
|
2903 |
}
|
2904 |
|
2905 |
-
|
2906 |
-
|
2907 |
|
2908 |
-
|
2909 |
-
|
2910 |
|
2911 |
-
|
2912 |
-
|
2913 |
|
2914 |
-
if(isParent && isOffsetRelative)
|
|
|
|
|
2915 |
|
2916 |
-
if (woset +
|
2917 |
-
|
2918 |
-
if (pRatio)
|
|
|
|
|
2919 |
}
|
2920 |
|
2921 |
-
if (hoset +
|
2922 |
-
|
2923 |
-
if (pRatio)
|
|
|
|
|
2924 |
}
|
2925 |
},
|
2926 |
|
2927 |
-
stop: function(
|
2928 |
-
var
|
2929 |
-
|
2930 |
-
|
2931 |
-
|
|
|
|
|
|
|
|
|
|
|
2932 |
|
2933 |
-
if (
|
2934 |
$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
|
|
|
2935 |
|
2936 |
-
if (
|
2937 |
$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2938 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2939 |
}
|
2940 |
});
|
2941 |
|
2942 |
$.ui.plugin.add("resizable", "ghost", {
|
2943 |
|
2944 |
-
start: function(
|
2945 |
|
2946 |
-
var
|
2947 |
|
2948 |
-
|
2949 |
-
|
2950 |
-
.css({ opacity: .25, display:
|
2951 |
-
.addClass(
|
2952 |
-
.addClass(typeof o.ghost
|
2953 |
|
2954 |
-
|
2955 |
|
2956 |
},
|
2957 |
|
2958 |
-
resize: function(
|
2959 |
-
var
|
2960 |
-
if (
|
|
|
|
|
2961 |
},
|
2962 |
|
2963 |
-
stop: function(
|
2964 |
-
var
|
2965 |
-
if (
|
|
|
|
|
2966 |
}
|
2967 |
|
2968 |
});
|
2969 |
|
2970 |
$.ui.plugin.add("resizable", "grid", {
|
2971 |
|
2972 |
-
resize: function(
|
2973 |
-
var
|
2974 |
-
|
2975 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2976 |
|
2977 |
if (/^(se|s|e)$/.test(a)) {
|
2978 |
-
|
2979 |
-
|
2980 |
-
}
|
2981 |
-
|
2982 |
-
|
2983 |
-
|
2984 |
-
|
2985 |
-
|
2986 |
-
|
2987 |
-
|
2988 |
-
|
2989 |
-
|
2990 |
-
|
2991 |
-
|
2992 |
-
|
2993 |
-
self.size.height = os.height + oy;
|
2994 |
-
self.position.top = op.top - oy;
|
2995 |
-
self.position.left = op.left - ox;
|
2996 |
}
|
2997 |
}
|
2998 |
|
2999 |
});
|
3000 |
|
3001 |
-
var num = function(v) {
|
3002 |
-
return parseInt(v, 10) || 0;
|
3003 |
-
};
|
3004 |
-
|
3005 |
-
var isNumber = function(value) {
|
3006 |
-
return !isNaN(parseInt(value, 10));
|
3007 |
-
};
|
3008 |
-
|
3009 |
})(jQuery);
|
3010 |
-
|
3011 |
-
* jQuery UI Selectable 1.8.17
|
3012 |
-
*
|
3013 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
3014 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
3015 |
-
* http://jquery.org/license
|
3016 |
-
*
|
3017 |
-
* http://docs.jquery.com/UI/Selectables
|
3018 |
-
*
|
3019 |
-
* Depends:
|
3020 |
-
* jquery.ui.core.js
|
3021 |
-
* jquery.ui.mouse.js
|
3022 |
-
* jquery.ui.widget.js
|
3023 |
-
*/
|
3024 |
(function( $, undefined ) {
|
3025 |
|
3026 |
$.widget("ui.selectable", $.ui.mouse, {
|
|
|
3027 |
options: {
|
3028 |
-
appendTo:
|
3029 |
autoRefresh: true,
|
3030 |
distance: 0,
|
3031 |
-
filter:
|
3032 |
-
tolerance:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3033 |
},
|
3034 |
_create: function() {
|
3035 |
-
var
|
|
|
3036 |
|
3037 |
this.element.addClass("ui-selectable");
|
3038 |
|
3039 |
this.dragged = false;
|
3040 |
|
3041 |
// cache selectee children based on filter
|
3042 |
-
var selectees;
|
3043 |
this.refresh = function() {
|
3044 |
-
selectees = $(
|
3045 |
selectees.addClass("ui-selectee");
|
3046 |
selectees.each(function() {
|
3047 |
-
var $this = $(this)
|
3048 |
-
|
3049 |
$.data(this, "selectable-item", {
|
3050 |
element: this,
|
3051 |
$element: $this,
|
@@ -3054,9 +3254,9 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3054 |
right: pos.left + $this.outerWidth(),
|
3055 |
bottom: pos.top + $this.outerHeight(),
|
3056 |
startselected: false,
|
3057 |
-
selected: $this.hasClass(
|
3058 |
-
selecting: $this.hasClass(
|
3059 |
-
unselecting: $this.hasClass(
|
3060 |
});
|
3061 |
});
|
3062 |
};
|
@@ -3069,28 +3269,24 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3069 |
this.helper = $("<div class='ui-selectable-helper'></div>");
|
3070 |
},
|
3071 |
|
3072 |
-
|
3073 |
this.selectees
|
3074 |
.removeClass("ui-selectee")
|
3075 |
.removeData("selectable-item");
|
3076 |
this.element
|
3077 |
-
.removeClass("ui-selectable ui-selectable-disabled")
|
3078 |
-
.removeData("selectable")
|
3079 |
-
.unbind(".selectable");
|
3080 |
this._mouseDestroy();
|
3081 |
-
|
3082 |
-
return this;
|
3083 |
},
|
3084 |
|
3085 |
_mouseStart: function(event) {
|
3086 |
-
var
|
|
|
3087 |
|
3088 |
this.opos = [event.pageX, event.pageY];
|
3089 |
|
3090 |
-
if (this.options.disabled)
|
3091 |
return;
|
3092 |
-
|
3093 |
-
var options = this.options;
|
3094 |
|
3095 |
this.selectees = $(options.filter, this.element[0]);
|
3096 |
|
@@ -3099,8 +3295,8 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3099 |
$(options.appendTo).append(this.helper);
|
3100 |
// position helper (lasso)
|
3101 |
this.helper.css({
|
3102 |
-
"left": event.
|
3103 |
-
"top": event.
|
3104 |
"width": 0,
|
3105 |
"height": 0
|
3106 |
});
|
@@ -3109,25 +3305,26 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3109 |
this.refresh();
|
3110 |
}
|
3111 |
|
3112 |
-
this.selectees.filter(
|
3113 |
var selectee = $.data(this, "selectable-item");
|
3114 |
selectee.startselected = true;
|
3115 |
if (!event.metaKey && !event.ctrlKey) {
|
3116 |
-
selectee.$element.removeClass(
|
3117 |
selectee.selected = false;
|
3118 |
-
selectee.$element.addClass(
|
3119 |
selectee.unselecting = true;
|
3120 |
// selectable UNSELECTING callback
|
3121 |
-
|
3122 |
unselecting: selectee.element
|
3123 |
});
|
3124 |
}
|
3125 |
});
|
3126 |
|
3127 |
-
$(event.target).parents().
|
3128 |
-
var
|
|
|
3129 |
if (selectee) {
|
3130 |
-
|
3131 |
selectee.$element
|
3132 |
.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
|
3133 |
.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
|
@@ -3136,11 +3333,11 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3136 |
selectee.selected = doSelect;
|
3137 |
// selectable (UN)SELECTING callback
|
3138 |
if (doSelect) {
|
3139 |
-
|
3140 |
selecting: selectee.element
|
3141 |
});
|
3142 |
} else {
|
3143 |
-
|
3144 |
unselecting: selectee.element
|
3145 |
});
|
3146 |
}
|
@@ -3151,46 +3348,55 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3151 |
},
|
3152 |
|
3153 |
_mouseDrag: function(event) {
|
3154 |
-
|
3155 |
this.dragged = true;
|
3156 |
|
3157 |
-
if (this.options.disabled)
|
3158 |
return;
|
|
|
3159 |
|
3160 |
-
var
|
|
|
|
|
|
|
|
|
|
|
|
|
3161 |
|
3162 |
-
|
3163 |
-
if (
|
3164 |
-
if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
|
3165 |
this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
|
3166 |
|
3167 |
this.selectees.each(function() {
|
3168 |
-
var selectee = $.data(this, "selectable-item")
|
|
|
|
|
3169 |
//prevent helper from being selected if appendTo: selectable
|
3170 |
-
if (!selectee || selectee.element
|
3171 |
return;
|
3172 |
-
|
3173 |
-
|
|
|
3174 |
hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
|
3175 |
-
} else if (options.tolerance
|
3176 |
hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
|
3177 |
}
|
3178 |
|
3179 |
if (hit) {
|
3180 |
// SELECT
|
3181 |
if (selectee.selected) {
|
3182 |
-
selectee.$element.removeClass(
|
3183 |
selectee.selected = false;
|
3184 |
}
|
3185 |
if (selectee.unselecting) {
|
3186 |
-
selectee.$element.removeClass(
|
3187 |
selectee.unselecting = false;
|
3188 |
}
|
3189 |
if (!selectee.selecting) {
|
3190 |
-
selectee.$element.addClass(
|
3191 |
selectee.selecting = true;
|
3192 |
// selectable SELECTING callback
|
3193 |
-
|
3194 |
selecting: selectee.element
|
3195 |
});
|
3196 |
}
|
@@ -3198,32 +3404,32 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3198 |
// UNSELECT
|
3199 |
if (selectee.selecting) {
|
3200 |
if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
|
3201 |
-
selectee.$element.removeClass(
|
3202 |
selectee.selecting = false;
|
3203 |
-
selectee.$element.addClass(
|
3204 |
selectee.selected = true;
|
3205 |
} else {
|
3206 |
-
selectee.$element.removeClass(
|
3207 |
selectee.selecting = false;
|
3208 |
if (selectee.startselected) {
|
3209 |
-
selectee.$element.addClass(
|
3210 |
selectee.unselecting = true;
|
3211 |
}
|
3212 |
// selectable UNSELECTING callback
|
3213 |
-
|
3214 |
unselecting: selectee.element
|
3215 |
});
|
3216 |
}
|
3217 |
}
|
3218 |
if (selectee.selected) {
|
3219 |
if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
|
3220 |
-
selectee.$element.removeClass(
|
3221 |
selectee.selected = false;
|
3222 |
|
3223 |
-
selectee.$element.addClass(
|
3224 |
selectee.unselecting = true;
|
3225 |
// selectable UNSELECTING callback
|
3226 |
-
|
3227 |
unselecting: selectee.element
|
3228 |
});
|
3229 |
}
|
@@ -3235,28 +3441,26 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3235 |
},
|
3236 |
|
3237 |
_mouseStop: function(event) {
|
3238 |
-
var
|
3239 |
|
3240 |
this.dragged = false;
|
3241 |
|
3242 |
-
|
3243 |
-
|
3244 |
-
$('.ui-unselecting', this.element[0]).each(function() {
|
3245 |
var selectee = $.data(this, "selectable-item");
|
3246 |
-
selectee.$element.removeClass(
|
3247 |
selectee.unselecting = false;
|
3248 |
selectee.startselected = false;
|
3249 |
-
|
3250 |
unselected: selectee.element
|
3251 |
});
|
3252 |
});
|
3253 |
-
$(
|
3254 |
var selectee = $.data(this, "selectable-item");
|
3255 |
-
selectee.$element.removeClass(
|
3256 |
selectee.selecting = false;
|
3257 |
selectee.selected = true;
|
3258 |
selectee.startselected = true;
|
3259 |
-
|
3260 |
selected: selectee.element
|
3261 |
});
|
3262 |
});
|
@@ -3269,35 +3473,30 @@ $.widget("ui.selectable", $.ui.mouse, {
|
|
3269 |
|
3270 |
});
|
3271 |
|
3272 |
-
$.extend($.ui.selectable, {
|
3273 |
-
version: "1.8.17"
|
3274 |
-
});
|
3275 |
-
|
3276 |
})(jQuery);
|
3277 |
-
|
3278 |
-
* jQuery UI Sortable 1.8.17
|
3279 |
-
*
|
3280 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
3281 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
3282 |
-
* http://jquery.org/license
|
3283 |
-
*
|
3284 |
-
* http://docs.jquery.com/UI/Sortables
|
3285 |
-
*
|
3286 |
-
* Depends:
|
3287 |
-
* jquery.ui.core.js
|
3288 |
-
* jquery.ui.mouse.js
|
3289 |
-
* jquery.ui.widget.js
|
3290 |
-
*/
|
3291 |
(function( $, undefined ) {
|
3292 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3293 |
$.widget("ui.sortable", $.ui.mouse, {
|
|
|
3294 |
widgetEventPrefix: "sort",
|
|
|
3295 |
options: {
|
3296 |
appendTo: "parent",
|
3297 |
axis: false,
|
3298 |
connectWith: false,
|
3299 |
containment: false,
|
3300 |
-
cursor:
|
3301 |
cursorAt: false,
|
3302 |
dropOnEmpty: true,
|
3303 |
forcePlaceholderSize: false,
|
@@ -3305,7 +3504,7 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3305 |
grid: false,
|
3306 |
handle: false,
|
3307 |
helper: "original",
|
3308 |
-
items:
|
3309 |
opacity: false,
|
3310 |
placeholder: false,
|
3311 |
revert: false,
|
@@ -3314,7 +3513,21 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3314 |
scrollSpeed: 20,
|
3315 |
scope: "default",
|
3316 |
tolerance: "intersect",
|
3317 |
-
zIndex: 1000
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3318 |
},
|
3319 |
_create: function() {
|
3320 |
|
@@ -3326,7 +3539,7 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3326 |
this.refresh();
|
3327 |
|
3328 |
//Let's determine if the items are being displayed horizontally
|
3329 |
-
this.floating = this.items.length ? o.axis ===
|
3330 |
|
3331 |
//Let's determine the parent's offset
|
3332 |
this.offset = this.element.offset();
|
@@ -3334,15 +3547,19 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3334 |
//Initialize mouse events for interaction
|
3335 |
this._mouseInit();
|
3336 |
|
|
|
|
|
|
|
3337 |
},
|
3338 |
|
3339 |
-
|
3340 |
this.element
|
3341 |
.removeClass("ui-sortable ui-sortable-disabled");
|
3342 |
this._mouseDestroy();
|
3343 |
|
3344 |
-
for ( var i = this.items.length - 1; i >= 0; i-- )
|
3345 |
this.items[i].item.removeData(this.widgetName + "-item");
|
|
|
3346 |
|
3347 |
return this;
|
3348 |
},
|
@@ -3350,9 +3567,8 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3350 |
_setOption: function(key, value){
|
3351 |
if ( key === "disabled" ) {
|
3352 |
this.options[ key ] = value;
|
3353 |
-
|
3354 |
-
this.widget()
|
3355 |
-
[ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
|
3356 |
} else {
|
3357 |
// Don't call widget base _setOption for disable as it adds ui-state-disabled class
|
3358 |
$.Widget.prototype._setOption.apply(this, arguments);
|
@@ -3360,32 +3576,44 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3360 |
},
|
3361 |
|
3362 |
_mouseCapture: function(event, overrideHandle) {
|
3363 |
-
var
|
|
|
|
|
3364 |
|
3365 |
if (this.reverting) {
|
3366 |
return false;
|
3367 |
}
|
3368 |
|
3369 |
-
if(this.options.disabled || this.options.type
|
|
|
|
|
3370 |
|
3371 |
//We have to refresh the items data once first
|
3372 |
this._refreshItems(event);
|
3373 |
|
3374 |
//Find out if the clicked node (or one of its parents) is a actual item in this.items
|
3375 |
-
|
3376 |
-
if($.data(this, that.widgetName +
|
3377 |
currentItem = $(this);
|
3378 |
return false;
|
3379 |
}
|
3380 |
});
|
3381 |
-
if($.data(event.target, that.widgetName +
|
|
|
|
|
3382 |
|
3383 |
-
if(!currentItem)
|
|
|
|
|
3384 |
if(this.options.handle && !overrideHandle) {
|
3385 |
-
|
3386 |
-
|
3387 |
-
|
3388 |
-
|
|
|
|
|
|
|
|
|
3389 |
}
|
3390 |
|
3391 |
this.currentItem = currentItem;
|
@@ -3396,7 +3624,9 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3396 |
|
3397 |
_mouseStart: function(event, overrideHandle, noActivation) {
|
3398 |
|
3399 |
-
var
|
|
|
|
|
3400 |
this.currentContainer = this;
|
3401 |
|
3402 |
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
|
@@ -3426,11 +3656,6 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3426 |
left: this.offset.left - this.margins.left
|
3427 |
};
|
3428 |
|
3429 |
-
// Only after we got the offset, we can change the helper's position to absolute
|
3430 |
-
// TODO: Still need to figure out a way to make relative sorting possible
|
3431 |
-
this.helper.css("position", "absolute");
|
3432 |
-
this.cssPosition = this.helper.css("position");
|
3433 |
-
|
3434 |
$.extend(this.offset, {
|
3435 |
click: { //Where the click happened, relative to the element
|
3436 |
left: event.pageX - this.offset.left,
|
@@ -3440,19 +3665,24 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3440 |
relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
|
3441 |
});
|
3442 |
|
|
|
|
|
|
|
|
|
|
|
3443 |
//Generate the original position
|
3444 |
this.originalPosition = this._generatePosition(event);
|
3445 |
this.originalPageX = event.pageX;
|
3446 |
this.originalPageY = event.pageY;
|
3447 |
|
3448 |
-
//Adjust the mouse offset relative to the helper if
|
3449 |
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
|
3450 |
|
3451 |
//Cache the former DOM position
|
3452 |
this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
|
3453 |
|
3454 |
//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
|
3455 |
-
if(this.helper[0]
|
3456 |
this.currentItem.hide();
|
3457 |
}
|
3458 |
|
@@ -3460,47 +3690,63 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3460 |
this._createPlaceholder();
|
3461 |
|
3462 |
//Set a containment if given in the options
|
3463 |
-
if(o.containment)
|
3464 |
this._setContainment();
|
|
|
|
|
|
|
|
|
3465 |
|
3466 |
-
|
3467 |
-
|
3468 |
-
|
|
|
|
|
3469 |
}
|
3470 |
|
3471 |
if(o.opacity) { // opacity option
|
3472 |
-
if (this.helper.css("opacity"))
|
|
|
|
|
3473 |
this.helper.css("opacity", o.opacity);
|
3474 |
}
|
3475 |
|
3476 |
if(o.zIndex) { // zIndex option
|
3477 |
-
if (this.helper.css("zIndex"))
|
|
|
|
|
3478 |
this.helper.css("zIndex", o.zIndex);
|
3479 |
}
|
3480 |
|
3481 |
//Prepare scrolling
|
3482 |
-
if(this.scrollParent[0]
|
3483 |
this.overflowOffset = this.scrollParent.offset();
|
|
|
3484 |
|
3485 |
//Call callbacks
|
3486 |
this._trigger("start", event, this._uiHash());
|
3487 |
|
3488 |
//Recache the helper size
|
3489 |
-
if(!this._preserveHelperProportions)
|
3490 |
this._cacheHelperProportions();
|
|
|
3491 |
|
3492 |
|
3493 |
-
//Post
|
3494 |
-
if(!noActivation) {
|
3495 |
-
|
|
|
|
|
3496 |
}
|
3497 |
|
3498 |
//Prepare possible droppables
|
3499 |
-
if($.ui.ddmanager)
|
3500 |
$.ui.ddmanager.current = this;
|
|
|
3501 |
|
3502 |
-
if ($.ui.ddmanager && !o.dropBehaviour)
|
3503 |
$.ui.ddmanager.prepareOffsets(this, event);
|
|
|
3504 |
|
3505 |
this.dragging = true;
|
3506 |
|
@@ -3511,6 +3757,9 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3511 |
},
|
3512 |
|
3513 |
_mouseDrag: function(event) {
|
|
|
|
|
|
|
3514 |
|
3515 |
//Compute the helpers position
|
3516 |
this.position = this._generatePosition(event);
|
@@ -3522,61 +3771,86 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3522 |
|
3523 |
//Do scrolling
|
3524 |
if(this.options.scroll) {
|
3525 |
-
|
3526 |
-
if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
|
3527 |
|
3528 |
-
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
|
3529 |
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
|
3530 |
-
else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
|
3531 |
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
|
|
|
3532 |
|
3533 |
-
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
|
3534 |
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
|
3535 |
-
else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
|
3536 |
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
|
|
|
3537 |
|
3538 |
} else {
|
3539 |
|
3540 |
-
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
|
3541 |
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
3542 |
-
else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
|
3543 |
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
|
|
3544 |
|
3545 |
-
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
|
3546 |
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
3547 |
-
else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
|
3548 |
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
|
|
3549 |
|
3550 |
}
|
3551 |
|
3552 |
-
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
|
3553 |
$.ui.ddmanager.prepareOffsets(this, event);
|
|
|
3554 |
}
|
3555 |
|
3556 |
//Regenerate the absolute position used for position checks
|
3557 |
this.positionAbs = this._convertPositionTo("absolute");
|
3558 |
|
3559 |
//Set the helper position
|
3560 |
-
if(!this.options.axis || this.options.axis
|
3561 |
-
|
|
|
|
|
|
|
|
|
3562 |
|
3563 |
//Rearrange
|
3564 |
-
for (
|
3565 |
|
3566 |
//Cache variables and intersection, continue if no intersection
|
3567 |
-
|
3568 |
-
|
3569 |
-
|
3570 |
-
if(
|
3571 |
-
|
3572 |
-
|
3573 |
-
|
3574 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3575 |
) {
|
3576 |
|
3577 |
-
this.direction = intersection
|
3578 |
|
3579 |
-
if (this.options.tolerance
|
3580 |
this._rearrange(event, item);
|
3581 |
} else {
|
3582 |
break;
|
@@ -3591,10 +3865,12 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3591 |
this._contactContainers(event);
|
3592 |
|
3593 |
//Interconnect with droppables
|
3594 |
-
if($.ui.ddmanager)
|
|
|
|
|
3595 |
|
3596 |
//Call callbacks
|
3597 |
-
this._trigger(
|
3598 |
|
3599 |
this.lastPositionAbs = this.positionAbs;
|
3600 |
return false;
|
@@ -3603,23 +3879,30 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3603 |
|
3604 |
_mouseStop: function(event, noPropagation) {
|
3605 |
|
3606 |
-
if(!event)
|
|
|
|
|
3607 |
|
3608 |
//If we are using droppables, inform the manager about the drop
|
3609 |
-
if ($.ui.ddmanager && !this.options.dropBehaviour)
|
3610 |
$.ui.ddmanager.drop(this, event);
|
|
|
3611 |
|
3612 |
if(this.options.revert) {
|
3613 |
-
var
|
3614 |
-
|
|
|
|
|
3615 |
|
3616 |
-
|
3617 |
-
|
3618 |
-
|
3619 |
-
|
3620 |
-
top
|
3621 |
-
}
|
3622 |
-
|
|
|
|
|
3623 |
});
|
3624 |
} else {
|
3625 |
this._clear(event, noPropagation);
|
@@ -3631,22 +3914,21 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3631 |
|
3632 |
cancel: function() {
|
3633 |
|
3634 |
-
var self = this;
|
3635 |
-
|
3636 |
if(this.dragging) {
|
3637 |
|
3638 |
this._mouseUp({ target: null });
|
3639 |
|
3640 |
-
if(this.options.helper
|
3641 |
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
|
3642 |
-
else
|
3643 |
this.currentItem.show();
|
|
|
3644 |
|
3645 |
//Post deactivating events to containers
|
3646 |
for (var i = this.containers.length - 1; i >= 0; i--){
|
3647 |
-
this.containers[i]._trigger("deactivate", null,
|
3648 |
if(this.containers[i].containerCache.over) {
|
3649 |
-
this.containers[i]._trigger("out", null,
|
3650 |
this.containers[i].containerCache.over = 0;
|
3651 |
}
|
3652 |
}
|
@@ -3655,8 +3937,12 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3655 |
|
3656 |
if (this.placeholder) {
|
3657 |
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
|
3658 |
-
if(this.placeholder[0].parentNode)
|
3659 |
-
|
|
|
|
|
|
|
|
|
3660 |
|
3661 |
$.extend(this, {
|
3662 |
helper: null,
|
@@ -3678,28 +3964,33 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3678 |
|
3679 |
serialize: function(o) {
|
3680 |
|
3681 |
-
var items = this._getItemsAsjQuery(o && o.connected)
|
3682 |
-
|
|
|
3683 |
|
3684 |
$(items).each(function() {
|
3685 |
-
var res = ($(o.item || this).attr(o.attribute ||
|
3686 |
-
if
|
|
|
|
|
3687 |
});
|
3688 |
|
3689 |
if(!str.length && o.key) {
|
3690 |
-
str.push(o.key +
|
3691 |
}
|
3692 |
|
3693 |
-
return str.join(
|
3694 |
|
3695 |
},
|
3696 |
|
3697 |
toArray: function(o) {
|
3698 |
|
3699 |
-
var items = this._getItemsAsjQuery(o && o.connected)
|
3700 |
-
|
|
|
|
|
3701 |
|
3702 |
-
items.each(function() { ret.push($(o.item || this).attr(o.attribute ||
|
3703 |
return ret;
|
3704 |
|
3705 |
},
|
@@ -3710,73 +4001,71 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3710 |
var x1 = this.positionAbs.left,
|
3711 |
x2 = x1 + this.helperProportions.width,
|
3712 |
y1 = this.positionAbs.top,
|
3713 |
-
y2 = y1 + this.helperProportions.height
|
3714 |
-
|
3715 |
-
var l = item.left,
|
3716 |
r = l + item.width,
|
3717 |
t = item.top,
|
3718 |
-
b = t + item.height
|
3719 |
-
|
3720 |
-
|
3721 |
-
|
3722 |
-
|
3723 |
-
|
3724 |
-
|
3725 |
-
|
3726 |
-
|| this.options.forcePointerForContainers
|
3727 |
-
|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
|
3728 |
) {
|
3729 |
return isOverElement;
|
3730 |
} else {
|
3731 |
|
3732 |
-
return (l < x1 + (this.helperProportions.width / 2) // Right Half
|
3733 |
-
|
3734 |
-
|
3735 |
-
|
3736 |
|
3737 |
}
|
3738 |
},
|
3739 |
|
3740 |
_intersectsWithPointer: function(item) {
|
3741 |
|
3742 |
-
var isOverElementHeight =
|
3743 |
-
isOverElementWidth =
|
3744 |
isOverElement = isOverElementHeight && isOverElementWidth,
|
3745 |
verticalDirection = this._getDragVerticalDirection(),
|
3746 |
horizontalDirection = this._getDragHorizontalDirection();
|
3747 |
|
3748 |
-
if (!isOverElement)
|
3749 |
return false;
|
|
|
3750 |
|
3751 |
return this.floating ?
|
3752 |
-
( ((horizontalDirection && horizontalDirection
|
3753 |
-
: ( verticalDirection && (verticalDirection
|
3754 |
|
3755 |
},
|
3756 |
|
3757 |
_intersectsWithSides: function(item) {
|
3758 |
|
3759 |
-
var isOverBottomHalf =
|
3760 |
-
isOverRightHalf =
|
3761 |
verticalDirection = this._getDragVerticalDirection(),
|
3762 |
horizontalDirection = this._getDragHorizontalDirection();
|
3763 |
|
3764 |
if (this.floating && horizontalDirection) {
|
3765 |
-
return ((horizontalDirection
|
3766 |
} else {
|
3767 |
-
return verticalDirection && ((verticalDirection
|
3768 |
}
|
3769 |
|
3770 |
},
|
3771 |
|
3772 |
_getDragVerticalDirection: function() {
|
3773 |
var delta = this.positionAbs.top - this.lastPositionAbs.top;
|
3774 |
-
return delta
|
3775 |
},
|
3776 |
|
3777 |
_getDragHorizontalDirection: function() {
|
3778 |
var delta = this.positionAbs.left - this.lastPositionAbs.left;
|
3779 |
-
return delta
|
3780 |
},
|
3781 |
|
3782 |
refresh: function(event) {
|
@@ -3787,37 +4076,35 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3787 |
|
3788 |
_connectWith: function() {
|
3789 |
var options = this.options;
|
3790 |
-
return options.connectWith.constructor
|
3791 |
-
? [options.connectWith]
|
3792 |
-
: options.connectWith;
|
3793 |
},
|
3794 |
-
|
3795 |
_getItemsAsjQuery: function(connected) {
|
3796 |
|
3797 |
-
var
|
3798 |
-
|
3799 |
-
|
3800 |
-
|
3801 |
|
3802 |
if(connectWith && connected) {
|
3803 |
-
for (
|
3804 |
-
|
3805 |
-
for (
|
3806 |
-
|
3807 |
-
if(inst && inst
|
3808 |
-
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(
|
3809 |
}
|
3810 |
-
}
|
3811 |
-
}
|
3812 |
}
|
3813 |
|
3814 |
-
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(
|
3815 |
|
3816 |
-
for (
|
3817 |
queries[i][0].each(function() {
|
3818 |
items.push(this);
|
3819 |
});
|
3820 |
-
}
|
3821 |
|
3822 |
return $(items);
|
3823 |
|
@@ -3827,14 +4114,14 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3827 |
|
3828 |
var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
|
3829 |
|
3830 |
-
|
3831 |
-
|
3832 |
for (var j=0; j < list.length; j++) {
|
3833 |
-
if(list[j]
|
3834 |
-
|
3835 |
-
|
3836 |
-
|
3837 |
-
|
|
|
3838 |
|
3839 |
},
|
3840 |
|
@@ -3842,32 +4129,33 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3842 |
|
3843 |
this.items = [];
|
3844 |
this.containers = [this];
|
3845 |
-
|
3846 |
-
var
|
3847 |
-
|
3848 |
-
|
3849 |
-
|
3850 |
-
|
3851 |
-
|
3852 |
-
|
3853 |
-
|
3854 |
-
|
3855 |
-
|
|
|
3856 |
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
|
3857 |
this.containers.push(inst);
|
3858 |
}
|
3859 |
-
}
|
3860 |
-
}
|
3861 |
}
|
3862 |
|
3863 |
-
for (
|
3864 |
-
|
3865 |
-
|
3866 |
|
3867 |
-
for (
|
3868 |
-
|
3869 |
|
3870 |
-
item.data(this.widgetName +
|
3871 |
|
3872 |
items.push({
|
3873 |
item: item,
|
@@ -3875,8 +4163,8 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3875 |
width: 0, height: 0,
|
3876 |
left: 0, top: 0
|
3877 |
});
|
3878 |
-
}
|
3879 |
-
}
|
3880 |
|
3881 |
},
|
3882 |
|
@@ -3887,105 +4175,124 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3887 |
this.offset.parent = this._getParentOffset();
|
3888 |
}
|
3889 |
|
3890 |
-
|
3891 |
-
|
|
|
|
|
3892 |
|
3893 |
//We ignore calculating positions of all connected containers when we're not over them
|
3894 |
-
if(item.instance
|
3895 |
continue;
|
|
|
3896 |
|
3897 |
-
|
3898 |
|
3899 |
if (!fast) {
|
3900 |
item.width = t.outerWidth();
|
3901 |
item.height = t.outerHeight();
|
3902 |
}
|
3903 |
|
3904 |
-
|
3905 |
item.left = p.left;
|
3906 |
item.top = p.top;
|
3907 |
-
}
|
3908 |
|
3909 |
if(this.options.custom && this.options.custom.refreshContainers) {
|
3910 |
this.options.custom.refreshContainers.call(this);
|
3911 |
} else {
|
3912 |
-
for (
|
3913 |
-
|
3914 |
this.containers[i].containerCache.left = p.left;
|
3915 |
this.containers[i].containerCache.top = p.top;
|
3916 |
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
|
3917 |
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
|
3918 |
-
}
|
3919 |
}
|
3920 |
|
3921 |
return this;
|
3922 |
},
|
3923 |
|
3924 |
_createPlaceholder: function(that) {
|
|
|
|
|
|
|
3925 |
|
3926 |
-
|
3927 |
-
|
3928 |
-
if(!o.placeholder || o.placeholder.constructor == String) {
|
3929 |
-
var className = o.placeholder;
|
3930 |
o.placeholder = {
|
3931 |
element: function() {
|
3932 |
|
3933 |
-
var
|
3934 |
-
|
3935 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3936 |
|
3937 |
-
if(!className)
|
3938 |
-
|
|
|
3939 |
|
3940 |
-
return
|
3941 |
},
|
3942 |
update: function(container, p) {
|
3943 |
|
3944 |
// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
|
3945 |
// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
|
3946 |
-
if(className && !o.forcePlaceholderSize)
|
|
|
|
|
3947 |
|
3948 |
//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
|
3949 |
-
if(!p.height()) { p.height(
|
3950 |
-
if(!p.width()) { p.width(
|
3951 |
}
|
3952 |
};
|
3953 |
}
|
3954 |
|
3955 |
//Create the placeholder
|
3956 |
-
|
3957 |
|
3958 |
//Append it after the actual current item
|
3959 |
-
|
3960 |
|
3961 |
//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
|
3962 |
-
o.placeholder.update(
|
3963 |
|
3964 |
},
|
3965 |
|
3966 |
_contactContainers: function(event) {
|
3967 |
-
|
3968 |
-
|
3969 |
-
|
3970 |
-
|
3971 |
-
|
3972 |
-
for (var i = this.containers.length - 1; i >= 0; i--){
|
3973 |
-
|
3974 |
-
// never consider a container that's located within the item itself
|
3975 |
-
if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
|
3976 |
-
continue;
|
3977 |
|
3978 |
-
|
|
|
3979 |
|
3980 |
-
|
3981 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3982 |
continue;
|
|
|
3983 |
|
3984 |
-
innermostContainer = this.containers[i];
|
3985 |
innermostIndex = i;
|
3986 |
-
|
3987 |
} else {
|
3988 |
-
// container doesn't intersect. trigger "out" event if necessary
|
3989 |
if(this.containers[i].containerCache.over) {
|
3990 |
this.containers[i]._trigger("out", event, this._uiHash(this));
|
3991 |
this.containers[i].containerCache.over = 0;
|
@@ -3993,79 +4300,116 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
3993 |
}
|
3994 |
|
3995 |
}
|
3996 |
-
|
3997 |
-
// if no intersecting containers found, return
|
3998 |
-
if(!innermostContainer)
|
|
|
|
|
3999 |
|
4000 |
// move the item into the container if it's not there already
|
4001 |
if(this.containers.length === 1) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4002 |
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
|
4003 |
this.containers[innermostIndex].containerCache.over = 1;
|
4004 |
-
}
|
4005 |
-
|
4006 |
-
|
4007 |
-
var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
|
4008 |
-
for (var j = this.items.length - 1; j >= 0; j--) {
|
4009 |
-
if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
|
4010 |
-
var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
|
4011 |
-
if(Math.abs(cur - base) < dist) {
|
4012 |
-
dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
|
4013 |
-
}
|
4014 |
-
}
|
4015 |
-
|
4016 |
-
if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
|
4017 |
-
return;
|
4018 |
-
|
4019 |
-
this.currentContainer = this.containers[innermostIndex];
|
4020 |
-
itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
|
4021 |
-
this._trigger("change", event, this._uiHash());
|
4022 |
-
this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
|
4023 |
-
|
4024 |
-
//Update the placeholder
|
4025 |
-
this.options.placeholder.update(this.currentContainer, this.placeholder);
|
4026 |
-
|
4027 |
-
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
|
4028 |
-
this.containers[innermostIndex].containerCache.over = 1;
|
4029 |
-
}
|
4030 |
-
|
4031 |
-
|
4032 |
},
|
4033 |
|
4034 |
_createHelper: function(event) {
|
4035 |
|
4036 |
-
var o = this.options
|
4037 |
-
|
4038 |
|
4039 |
-
|
4040 |
-
|
|
|
|
|
4041 |
|
4042 |
-
if(helper[0]
|
4043 |
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") };
|
|
|
4044 |
|
4045 |
-
if(helper[0].style.width
|
4046 |
-
|
|
|
|
|
|
|
|
|
4047 |
|
4048 |
return helper;
|
4049 |
|
4050 |
},
|
4051 |
|
4052 |
_adjustOffsetFromHelper: function(obj) {
|
4053 |
-
if (typeof obj
|
4054 |
-
obj = obj.split(
|
4055 |
}
|
4056 |
if ($.isArray(obj)) {
|
4057 |
obj = {left: +obj[0], top: +obj[1] || 0};
|
4058 |
}
|
4059 |
-
if (
|
4060 |
this.offset.click.left = obj.left + this.margins.left;
|
4061 |
}
|
4062 |
-
if (
|
4063 |
this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
|
4064 |
}
|
4065 |
-
if (
|
4066 |
this.offset.click.top = obj.top + this.margins.top;
|
4067 |
}
|
4068 |
-
if (
|
4069 |
this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
|
4070 |
}
|
4071 |
},
|
@@ -4081,14 +4425,16 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4081 |
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
|
4082 |
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
|
4083 |
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
|
4084 |
-
if(this.cssPosition
|
4085 |
po.left += this.scrollParent.scrollLeft();
|
4086 |
po.top += this.scrollParent.scrollTop();
|
4087 |
}
|
4088 |
|
4089 |
-
|
4090 |
-
|
|
|
4091 |
po = { top: 0, left: 0 };
|
|
|
4092 |
|
4093 |
return {
|
4094 |
top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
|
@@ -4099,7 +4445,7 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4099 |
|
4100 |
_getRelativeOffset: function() {
|
4101 |
|
4102 |
-
if(this.cssPosition
|
4103 |
var p = this.currentItem.position();
|
4104 |
return {
|
4105 |
top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
|
@@ -4127,19 +4473,24 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4127 |
|
4128 |
_setContainment: function() {
|
4129 |
|
4130 |
-
var
|
4131 |
-
|
4132 |
-
if(o.containment
|
4133 |
-
|
4134 |
-
|
4135 |
-
|
4136 |
-
|
4137 |
-
|
|
|
|
|
|
|
|
|
|
|
4138 |
|
4139 |
if(!(/^(document|window|parent)$/).test(o.containment)) {
|
4140 |
-
|
4141 |
-
|
4142 |
-
|
4143 |
|
4144 |
this.containment = [
|
4145 |
co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
|
@@ -4153,22 +4504,25 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4153 |
|
4154 |
_convertPositionTo: function(d, pos) {
|
4155 |
|
4156 |
-
if(!pos)
|
4157 |
-
|
4158 |
-
|
|
|
|
|
|
|
4159 |
|
4160 |
return {
|
4161 |
top: (
|
4162 |
-
pos.top
|
4163 |
-
|
4164 |
-
|
4165 |
-
|
4166 |
),
|
4167 |
left: (
|
4168 |
-
pos.left // The absolute mouse position
|
4169 |
-
|
4170 |
-
|
4171 |
-
|
4172 |
)
|
4173 |
};
|
4174 |
|
@@ -4176,19 +4530,20 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4176 |
|
4177 |
_generatePosition: function(event) {
|
4178 |
|
4179 |
-
var
|
|
|
|
|
|
|
|
|
4180 |
|
4181 |
// This is another very weird special case that only happens for relative elements:
|
4182 |
// 1. If the css position is relative
|
4183 |
// 2. and the scroll parent is the document or similar to the offset parent
|
4184 |
// we have to refresh the relative offset during the scroll so there are no jumps
|
4185 |
-
if(this.cssPosition
|
4186 |
this.offset.relative = this._getRelativeOffset();
|
4187 |
}
|
4188 |
|
4189 |
-
var pageX = event.pageX;
|
4190 |
-
var pageY = event.pageY;
|
4191 |
-
|
4192 |
/*
|
4193 |
* - Position constraining -
|
4194 |
* Constrain the position to a mix of grid, containment.
|
@@ -4197,36 +4552,44 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4197 |
if(this.originalPosition) { //If we are not dragging yet, we won't check for options
|
4198 |
|
4199 |
if(this.containment) {
|
4200 |
-
if(event.pageX - this.offset.click.left < this.containment[0])
|
4201 |
-
|
4202 |
-
|
4203 |
-
if(event.pageY - this.offset.click.top
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4204 |
}
|
4205 |
|
4206 |
if(o.grid) {
|
4207 |
-
|
4208 |
-
pageY = this.containment ? (
|
4209 |
|
4210 |
-
|
4211 |
-
pageX = this.containment ? (
|
4212 |
}
|
4213 |
|
4214 |
}
|
4215 |
|
4216 |
return {
|
4217 |
top: (
|
4218 |
-
pageY // The absolute mouse position
|
4219 |
-
|
4220 |
-
|
4221 |
-
|
4222 |
-
|
4223 |
),
|
4224 |
left: (
|
4225 |
-
pageX // The absolute mouse position
|
4226 |
-
|
4227 |
-
|
4228 |
-
|
4229 |
-
|
4230 |
)
|
4231 |
};
|
4232 |
|
@@ -4234,7 +4597,7 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4234 |
|
4235 |
_rearrange: function(event, i, a, hardRefresh) {
|
4236 |
|
4237 |
-
a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction
|
4238 |
|
4239 |
//Various things done here to improve the performance:
|
4240 |
// 1. we create a setTimeout, that calls refreshPositions
|
@@ -4242,11 +4605,13 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4242 |
// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
|
4243 |
// 4. this lets only the last addition to the timeout stack through
|
4244 |
this.counter = this.counter ? ++this.counter : 1;
|
4245 |
-
var
|
4246 |
|
4247 |
-
|
4248 |
-
if(counter
|
4249 |
-
|
|
|
|
|
4250 |
|
4251 |
},
|
4252 |
|
@@ -4255,37 +4620,50 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4255 |
this.reverting = false;
|
4256 |
// We delay all events that have to be triggered to after the point where the placeholder has been removed and
|
4257 |
// everything else normalized again
|
4258 |
-
var
|
|
|
4259 |
|
4260 |
// We first have to update the dom position of the actual currentItem
|
4261 |
// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
|
4262 |
-
if(!this._noFinalSort && this.currentItem.parent().length)
|
|
|
|
|
4263 |
this._noFinalSort = null;
|
4264 |
|
4265 |
-
if(this.helper[0]
|
4266 |
-
for(
|
4267 |
-
if(this._storedCSS[i]
|
|
|
|
|
4268 |
}
|
4269 |
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
|
4270 |
} else {
|
4271 |
this.currentItem.show();
|
4272 |
}
|
4273 |
|
4274 |
-
if(this.fromOutside && !noPropagation)
|
4275 |
-
|
4276 |
-
|
4277 |
-
|
4278 |
-
|
4279 |
-
|
4280 |
-
|
4281 |
-
|
4282 |
-
|
4283 |
-
|
4284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
4285 |
|
4286 |
//Post events to containers
|
4287 |
-
for (
|
4288 |
-
if(!noPropagation)
|
|
|
|
|
4289 |
if(this.containers[i].containerCache.over) {
|
4290 |
delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
|
4291 |
this.containers[i].containerCache.over = 0;
|
@@ -4293,29 +4671,47 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4293 |
}
|
4294 |
|
4295 |
//Do what was originally in plugins
|
4296 |
-
if
|
4297 |
-
|
4298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4299 |
|
4300 |
this.dragging = false;
|
4301 |
if(this.cancelHelperRemoval) {
|
4302 |
if(!noPropagation) {
|
4303 |
this._trigger("beforeStop", event, this._uiHash());
|
4304 |
-
for (
|
|
|
|
|
4305 |
this._trigger("stop", event, this._uiHash());
|
4306 |
}
|
|
|
|
|
4307 |
return false;
|
4308 |
}
|
4309 |
|
4310 |
-
if(!noPropagation)
|
|
|
|
|
4311 |
|
4312 |
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
|
4313 |
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
|
4314 |
|
4315 |
-
if(this.helper[0]
|
|
|
|
|
|
|
4316 |
|
4317 |
if(!noPropagation) {
|
4318 |
-
for (
|
|
|
|
|
4319 |
this._trigger("stop", event, this._uiHash());
|
4320 |
}
|
4321 |
|
@@ -4330,7498 +4726,10262 @@ $.widget("ui.sortable", $.ui.mouse, {
|
|
4330 |
}
|
4331 |
},
|
4332 |
|
4333 |
-
_uiHash: function(
|
4334 |
-
var
|
4335 |
return {
|
4336 |
-
helper:
|
4337 |
-
placeholder:
|
4338 |
-
position:
|
4339 |
-
originalPosition:
|
4340 |
-
offset:
|
4341 |
-
item:
|
4342 |
-
sender:
|
4343 |
};
|
4344 |
}
|
4345 |
|
4346 |
});
|
4347 |
|
4348 |
-
$.extend($.ui.sortable, {
|
4349 |
-
version: "1.8.17"
|
4350 |
-
});
|
4351 |
-
|
4352 |
})(jQuery);
|
4353 |
-
|
4354 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4355 |
*
|
4356 |
-
* Copyright
|
4357 |
-
*
|
4358 |
* http://jquery.org/license
|
4359 |
*
|
4360 |
-
*
|
4361 |
-
*
|
4362 |
-
* Depends:
|
4363 |
-
* jquery.ui.core.js
|
4364 |
-
* jquery.ui.widget.js
|
4365 |
*/
|
4366 |
-
(function(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4367 |
|
4368 |
-
|
4369 |
-
|
4370 |
-
|
4371 |
-
|
4372 |
-
|
4373 |
-
|
4374 |
-
|
4375 |
-
|
4376 |
-
|
4377 |
-
|
4378 |
-
|
4379 |
-
|
4380 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4381 |
},
|
4382 |
-
|
4383 |
-
|
4384 |
-
|
|
|
|
|
|
|
4385 |
}
|
4386 |
},
|
|
|
4387 |
|
4388 |
-
|
4389 |
-
|
4390 |
-
options = self.options;
|
4391 |
|
4392 |
-
|
|
|
4393 |
|
4394 |
-
|
4395 |
-
|
4396 |
-
// in lack of child-selectors in CSS
|
4397 |
-
// we need to mark top-LIs in a UL-accordion for some IE-fix
|
4398 |
-
.children( "li" )
|
4399 |
-
.addClass( "ui-accordion-li-fix" );
|
4400 |
|
4401 |
-
|
4402 |
-
|
4403 |
-
|
4404 |
-
|
4405 |
-
|
4406 |
-
|
4407 |
-
|
4408 |
-
|
4409 |
-
|
4410 |
-
|
4411 |
-
|
4412 |
-
|
4413 |
-
|
4414 |
-
|
4415 |
-
.bind( "focus.accordion", function() {
|
4416 |
-
if ( options.disabled ) {
|
4417 |
-
return;
|
4418 |
-
}
|
4419 |
-
$( this ).addClass( "ui-state-focus" );
|
4420 |
-
})
|
4421 |
-
.bind( "blur.accordion", function() {
|
4422 |
-
if ( options.disabled ) {
|
4423 |
-
return;
|
4424 |
-
}
|
4425 |
-
$( this ).removeClass( "ui-state-focus" );
|
4426 |
-
});
|
4427 |
|
4428 |
-
|
4429 |
-
|
4430 |
|
4431 |
-
|
4432 |
-
|
4433 |
-
|
4434 |
-
|
4435 |
-
|
4436 |
-
|
4437 |
-
|
4438 |
-
|
4439 |
-
|
4440 |
-
|
4441 |
-
|
4442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4443 |
}
|
|
|
4444 |
|
4445 |
-
|
4446 |
-
|
4447 |
-
.toggleClass( "ui-corner-all" )
|
4448 |
-
.toggleClass( "ui-corner-top" );
|
4449 |
-
self.active.next().addClass( "ui-accordion-content-active" );
|
4450 |
|
4451 |
-
|
4452 |
-
|
4453 |
-
|
4454 |
-
|
4455 |
-
|
|
|
|
|
4456 |
|
4457 |
-
|
4458 |
-
|
4459 |
-
|
4460 |
-
return self._keydown( event );
|
4461 |
-
})
|
4462 |
-
.next()
|
4463 |
-
.attr( "role", "tabpanel" );
|
4464 |
|
4465 |
-
|
4466 |
-
|
4467 |
-
|
4468 |
-
|
4469 |
-
|
4470 |
-
|
4471 |
-
|
4472 |
-
.
|
4473 |
-
|
|
|
4474 |
|
4475 |
-
|
4476 |
-
|
4477 |
-
|
4478 |
-
|
4479 |
-
|
4480 |
-
|
4481 |
-
|
4482 |
-
|
4483 |
-
tabIndex: 0
|
4484 |
-
});
|
4485 |
}
|
4486 |
|
4487 |
-
|
4488 |
-
|
4489 |
-
self.headers.find( "a" ).attr( "tabIndex", -1 );
|
4490 |
}
|
4491 |
|
4492 |
-
if (
|
4493 |
-
|
4494 |
-
|
4495 |
-
event.preventDefault();
|
4496 |
});
|
|
|
4497 |
}
|
4498 |
-
},
|
4499 |
|
4500 |
-
|
4501 |
-
|
4502 |
-
|
4503 |
-
|
4504 |
-
|
4505 |
-
|
4506 |
-
|
4507 |
-
|
4508 |
-
|
4509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4510 |
}
|
4511 |
},
|
|
|
|
|
|
|
|
|
4512 |
|
4513 |
-
|
4514 |
-
|
4515 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4516 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4517 |
|
4518 |
-
|
4519 |
-
|
4520 |
-
|
4521 |
-
this.element
|
4522 |
-
.removeClass( "ui-accordion ui-widget ui-helper-reset" )
|
4523 |
-
.removeAttr( "role" );
|
4524 |
|
4525 |
-
|
4526 |
-
|
4527 |
-
|
4528 |
-
|
4529 |
-
|
4530 |
-
|
4531 |
-
.
|
|
|
|
|
4532 |
|
4533 |
-
|
4534 |
-
|
4535 |
-
|
4536 |
-
.css( "display", "" )
|
4537 |
-
.removeAttr( "role" )
|
4538 |
-
.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
|
4539 |
-
if ( options.autoHeight || options.fillHeight ) {
|
4540 |
-
contents.css( "height", "" );
|
4541 |
}
|
4542 |
|
4543 |
-
return
|
4544 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
4545 |
|
4546 |
-
|
4547 |
-
|
4548 |
-
|
4549 |
-
|
4550 |
-
|
4551 |
-
|
4552 |
-
|
4553 |
-
|
4554 |
-
|
4555 |
-
|
4556 |
-
}
|
4557 |
-
}
|
4558 |
-
// #5332 - opacity doesn't cascade to positioned elements in IE
|
4559 |
-
// so we need to add the disabled class to the headers and panels
|
4560 |
-
if ( key == "disabled" ) {
|
4561 |
-
this.headers.add(this.headers.next())
|
4562 |
-
[ value ? "addClass" : "removeClass" ](
|
4563 |
-
"ui-accordion-disabled ui-state-disabled" );
|
4564 |
}
|
|
|
4565 |
},
|
|
|
|
|
|
|
4566 |
|
4567 |
-
|
4568 |
-
|
4569 |
-
return;
|
4570 |
}
|
4571 |
|
4572 |
-
|
4573 |
-
length = this.headers.length,
|
4574 |
-
currentIndex = this.headers.index( event.target ),
|
4575 |
-
toFocus = false;
|
4576 |
|
4577 |
-
|
4578 |
-
|
4579 |
-
|
4580 |
-
|
4581 |
-
break;
|
4582 |
-
case keyCode.LEFT:
|
4583 |
-
case keyCode.UP:
|
4584 |
-
toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
|
4585 |
-
break;
|
4586 |
-
case keyCode.SPACE:
|
4587 |
-
case keyCode.ENTER:
|
4588 |
-
this._clickHandler( { target: event.target }, event.target );
|
4589 |
-
event.preventDefault();
|
4590 |
-
}
|
4591 |
-
|
4592 |
-
if ( toFocus ) {
|
4593 |
-
$( event.target ).attr( "tabIndex", -1 );
|
4594 |
-
$( toFocus ).attr( "tabIndex", 0 );
|
4595 |
-
toFocus.focus();
|
4596 |
-
return false;
|
4597 |
-
}
|
4598 |
-
|
4599 |
-
return true;
|
4600 |
},
|
|
|
|
|
|
|
|
|
|
|
4601 |
|
4602 |
-
|
4603 |
-
|
4604 |
-
maxHeight;
|
4605 |
|
4606 |
-
|
4607 |
-
|
4608 |
-
|
4609 |
-
|
4610 |
-
|
4611 |
-
|
4612 |
-
|
4613 |
-
|
4614 |
-
|
|
|
|
|
|
|
|
|
4615 |
|
4616 |
-
|
4617 |
-
|
4618 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4619 |
|
4620 |
-
|
4621 |
-
|
4622 |
-
|
4623 |
-
|
4624 |
-
|
4625 |
-
|
4626 |
-
|
4627 |
-
|
4628 |
-
|
4629 |
-
|
4630 |
-
|
4631 |
-
})
|
4632 |
-
.height( maxHeight );
|
4633 |
-
}
|
4634 |
|
4635 |
-
|
4636 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4637 |
|
4638 |
-
activate: function( index ) {
|
4639 |
-
// TODO this gets called on init, changing the option without an explicit call for that
|
4640 |
-
this.options.active = index;
|
4641 |
-
// call clickHandler with custom event
|
4642 |
-
var active = this._findActive( index )[ 0 ];
|
4643 |
-
this._clickHandler( { target: active }, active );
|
4644 |
|
4645 |
-
|
4646 |
-
|
|
|
|
|
|
|
4647 |
|
4648 |
-
|
4649 |
-
|
4650 |
-
? typeof selector === "number"
|
4651 |
-
? this.headers.filter( ":eq(" + selector + ")" )
|
4652 |
-
: this.headers.not( this.headers.not( selector ) )
|
4653 |
-
: selector === false
|
4654 |
-
? $( [] )
|
4655 |
-
: this.headers.filter( ":eq(0)" );
|
4656 |
-
},
|
4657 |
|
4658 |
-
|
4659 |
-
|
4660 |
-
|
4661 |
-
if ( options.disabled ) {
|
4662 |
-
return;
|
4663 |
}
|
4664 |
-
|
4665 |
-
|
4666 |
-
if ( !event.target ) {
|
4667 |
-
if ( !options.collapsible ) {
|
4668 |
-
return;
|
4669 |
-
}
|
4670 |
-
this.active
|
4671 |
-
.removeClass( "ui-state-active ui-corner-top" )
|
4672 |
-
.addClass( "ui-state-default ui-corner-all" )
|
4673 |
-
.children( ".ui-icon" )
|
4674 |
-
.removeClass( options.icons.headerSelected )
|
4675 |
-
.addClass( options.icons.header );
|
4676 |
-
this.active.next().addClass( "ui-accordion-content-active" );
|
4677 |
-
var toHide = this.active.next(),
|
4678 |
-
data = {
|
4679 |
-
options: options,
|
4680 |
-
newHeader: $( [] ),
|
4681 |
-
oldHeader: options.active,
|
4682 |
-
newContent: $( [] ),
|
4683 |
-
oldContent: toHide
|
4684 |
-
},
|
4685 |
-
toShow = ( this.active = $( [] ) );
|
4686 |
-
this._toggle( toShow, toHide, data );
|
4687 |
-
return;
|
4688 |
}
|
4689 |
|
4690 |
-
|
4691 |
-
|
4692 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4693 |
|
4694 |
-
|
4695 |
-
|
4696 |
-
|
4697 |
-
|
4698 |
-
|
|
|
|
|
|
|
4699 |
|
4700 |
-
|
4701 |
-
|
|
|
|
|
4702 |
return;
|
4703 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
4704 |
|
4705 |
-
|
4706 |
-
|
4707 |
-
|
4708 |
-
toHide = this.active.next(),
|
4709 |
-
data = {
|
4710 |
-
options: options,
|
4711 |
-
newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
|
4712 |
-
oldHeader: this.active,
|
4713 |
-
newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
|
4714 |
-
oldContent: toHide
|
4715 |
-
},
|
4716 |
-
down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
|
4717 |
-
|
4718 |
-
// when the call to ._toggle() comes after the class changes
|
4719 |
-
// it causes a very odd bug in IE 8 (see #6720)
|
4720 |
-
this.active = clickedIsActive ? $([]) : clicked;
|
4721 |
-
this._toggle( toShow, toHide, data, clickedIsActive, down );
|
4722 |
-
|
4723 |
-
// switch classes
|
4724 |
-
active
|
4725 |
-
.removeClass( "ui-state-active ui-corner-top" )
|
4726 |
-
.addClass( "ui-state-default ui-corner-all" )
|
4727 |
-
.children( ".ui-icon" )
|
4728 |
-
.removeClass( options.icons.headerSelected )
|
4729 |
-
.addClass( options.icons.header );
|
4730 |
-
if ( !clickedIsActive ) {
|
4731 |
-
clicked
|
4732 |
-
.removeClass( "ui-state-default ui-corner-all" )
|
4733 |
-
.addClass( "ui-state-active ui-corner-top" )
|
4734 |
-
.children( ".ui-icon" )
|
4735 |
-
.removeClass( options.icons.header )
|
4736 |
-
.addClass( options.icons.headerSelected );
|
4737 |
-
clicked
|
4738 |
-
.next()
|
4739 |
-
.addClass( "ui-accordion-content-active" );
|
4740 |
-
}
|
4741 |
|
4742 |
-
|
4743 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4744 |
|
4745 |
-
|
4746 |
-
|
4747 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4748 |
|
4749 |
-
|
4750 |
-
|
4751 |
-
|
|
|
4752 |
|
4753 |
-
|
4754 |
-
|
4755 |
-
|
|
|
|
|
|
|
|
|
4756 |
}
|
4757 |
-
return self._completed.apply( self, arguments );
|
4758 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4759 |
|
4760 |
-
|
4761 |
-
self._trigger( "changestart", null, self.data );
|
4762 |
|
4763 |
-
|
4764 |
-
self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
|
4765 |
|
4766 |
-
|
4767 |
-
|
|
|
4768 |
|
4769 |
-
|
4770 |
-
|
4771 |
-
|
4772 |
-
|
4773 |
-
|
4774 |
-
|
4775 |
-
autoHeight: options.autoHeight || options.fillSpace
|
4776 |
-
};
|
4777 |
-
} else {
|
4778 |
-
animOptions = {
|
4779 |
-
toShow: toShow,
|
4780 |
-
toHide: toHide,
|
4781 |
-
complete: complete,
|
4782 |
-
down: down,
|
4783 |
-
autoHeight: options.autoHeight || options.fillSpace
|
4784 |
-
};
|
4785 |
-
}
|
4786 |
|
4787 |
-
|
4788 |
-
|
4789 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4790 |
|
4791 |
-
|
4792 |
-
|
4793 |
-
|
|
|
|
|
|
|
|
|
4794 |
|
4795 |
-
|
4796 |
-
|
4797 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4798 |
|
4799 |
-
|
4800 |
-
|
4801 |
-
|
|
|
|
|
|
|
|
|
|
|
4802 |
|
4803 |
-
|
4804 |
-
|
4805 |
-
|
|
|
|
|
|
|
4806 |
|
4807 |
-
|
4808 |
-
|
|
|
|
|
|
|
|
|
4809 |
}
|
4810 |
-
|
4811 |
-
|
4812 |
-
|
4813 |
-
|
4814 |
-
|
4815 |
-
|
4816 |
-
};
|
4817 |
}
|
|
|
|
|
4818 |
|
4819 |
-
|
4820 |
-
|
4821 |
-
if ( options.collapsible && clickedIsActive ) {
|
4822 |
-
toShow.toggle();
|
4823 |
-
} else {
|
4824 |
-
toHide.hide();
|
4825 |
-
toShow.show();
|
4826 |
-
}
|
4827 |
|
4828 |
-
complete( true );
|
4829 |
-
}
|
4830 |
|
4831 |
-
|
4832 |
-
|
4833 |
-
|
4834 |
-
"aria-expanded": "false",
|
4835 |
-
"aria-selected": "false",
|
4836 |
-
tabIndex: -1
|
4837 |
-
})
|
4838 |
-
.blur();
|
4839 |
-
toShow.prev()
|
4840 |
-
.attr({
|
4841 |
-
"aria-expanded": "true",
|
4842 |
-
"aria-selected": "true",
|
4843 |
-
tabIndex: 0
|
4844 |
-
})
|
4845 |
-
.focus();
|
4846 |
-
},
|
4847 |
|
4848 |
-
|
4849 |
-
|
4850 |
-
if (
|
4851 |
-
|
|
|
|
|
|
|
|
|
4852 |
}
|
|
|
4853 |
|
4854 |
-
|
4855 |
-
|
4856 |
-
height: "",
|
4857 |
-
overflow: ""
|
4858 |
-
});
|
4859 |
-
}
|
4860 |
|
4861 |
-
|
4862 |
-
|
4863 |
-
|
4864 |
-
|
4865 |
-
this.
|
4866 |
-
|
|
|
|
|
4867 |
|
4868 |
-
|
4869 |
-
|
4870 |
-
});
|
4871 |
|
4872 |
-
|
4873 |
-
|
4874 |
-
|
4875 |
-
|
4876 |
-
|
4877 |
-
easing: "swing",
|
4878 |
-
duration: 300
|
4879 |
-
}, options, additions );
|
4880 |
-
if ( !options.toHide.size() ) {
|
4881 |
-
options.toShow.animate({
|
4882 |
-
height: "show",
|
4883 |
-
paddingTop: "show",
|
4884 |
-
paddingBottom: "show"
|
4885 |
-
}, options );
|
4886 |
-
return;
|
4887 |
-
}
|
4888 |
-
if ( !options.toShow.size() ) {
|
4889 |
-
options.toHide.animate({
|
4890 |
-
height: "hide",
|
4891 |
-
paddingTop: "hide",
|
4892 |
-
paddingBottom: "hide"
|
4893 |
-
}, options );
|
4894 |
-
return;
|
4895 |
-
}
|
4896 |
-
var overflow = options.toShow.css( "overflow" ),
|
4897 |
-
percentDone = 0,
|
4898 |
-
showProps = {},
|
4899 |
-
hideProps = {},
|
4900 |
-
fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
|
4901 |
-
originalWidth;
|
4902 |
-
// fix width before calculating height of hidden element
|
4903 |
-
var s = options.toShow;
|
4904 |
-
originalWidth = s[0].style.width;
|
4905 |
-
s.width( s.parent().width()
|
4906 |
-
- parseFloat( s.css( "paddingLeft" ) )
|
4907 |
-
- parseFloat( s.css( "paddingRight" ) )
|
4908 |
-
- ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 )
|
4909 |
-
- ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) );
|
4910 |
-
|
4911 |
-
$.each( fxAttrs, function( i, prop ) {
|
4912 |
-
hideProps[ prop ] = "hide";
|
4913 |
-
|
4914 |
-
var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
|
4915 |
-
showProps[ prop ] = {
|
4916 |
-
value: parts[ 1 ],
|
4917 |
-
unit: parts[ 2 ] || "px"
|
4918 |
-
};
|
4919 |
-
});
|
4920 |
-
options.toShow.css({ height: 0, overflow: "hidden" }).show();
|
4921 |
-
options.toHide
|
4922 |
-
.filter( ":hidden" )
|
4923 |
-
.each( options.complete )
|
4924 |
-
.end()
|
4925 |
-
.filter( ":visible" )
|
4926 |
-
.animate( hideProps, {
|
4927 |
-
step: function( now, settings ) {
|
4928 |
-
// only calculate the percent when animating height
|
4929 |
-
// IE gets very inconsistent results when animating elements
|
4930 |
-
// with small values, which is common for padding
|
4931 |
-
if ( settings.prop == "height" ) {
|
4932 |
-
percentDone = ( settings.end - settings.start === 0 ) ? 0 :
|
4933 |
-
( settings.now - settings.start ) / ( settings.end - settings.start );
|
4934 |
-
}
|
4935 |
|
4936 |
-
|
4937 |
-
|
4938 |
-
|
4939 |
-
|
4940 |
-
|
4941 |
-
|
4942 |
-
|
4943 |
-
|
4944 |
-
|
4945 |
-
|
4946 |
-
|
4947 |
-
|
4948 |
-
|
4949 |
-
|
4950 |
-
options.complete();
|
4951 |
}
|
4952 |
});
|
4953 |
-
}
|
4954 |
-
|
4955 |
-
|
4956 |
-
|
4957 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4958 |
});
|
4959 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4960 |
}
|
4961 |
});
|
4962 |
|
4963 |
-
})(
|
4964 |
-
/*
|
4965 |
-
* jQuery UI Autocomplete 1.8.17
|
4966 |
-
*
|
4967 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
4968 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
4969 |
-
* http://jquery.org/license
|
4970 |
-
*
|
4971 |
-
* http://docs.jquery.com/UI/Autocomplete
|
4972 |
-
*
|
4973 |
-
* Depends:
|
4974 |
-
* jquery.ui.core.js
|
4975 |
-
* jquery.ui.widget.js
|
4976 |
-
* jquery.ui.position.js
|
4977 |
-
*/
|
4978 |
-
(function( $, undefined ) {
|
4979 |
|
4980 |
-
|
4981 |
-
|
|
|
4982 |
|
4983 |
-
|
4984 |
-
options: {
|
4985 |
-
appendTo: "body",
|
4986 |
-
autoFocus: false,
|
4987 |
-
delay: 300,
|
4988 |
-
minLength: 1,
|
4989 |
-
position: {
|
4990 |
-
my: "left top",
|
4991 |
-
at: "left bottom",
|
4992 |
-
collision: "none"
|
4993 |
-
},
|
4994 |
-
source: null
|
4995 |
-
},
|
4996 |
|
4997 |
-
|
|
|
4998 |
|
4999 |
-
|
5000 |
-
|
5001 |
-
|
5002 |
-
|
|
|
|
|
|
|
|
|
5003 |
|
5004 |
-
|
5005 |
-
|
5006 |
-
|
5007 |
-
|
5008 |
-
|
5009 |
-
|
5010 |
-
|
5011 |
-
|
5012 |
-
|
5013 |
-
|
5014 |
-
|
5015 |
-
|
|
|
5016 |
}
|
5017 |
-
|
5018 |
-
|
5019 |
-
var keyCode = $.ui.keyCode;
|
5020 |
-
switch( event.keyCode ) {
|
5021 |
-
case keyCode.PAGE_UP:
|
5022 |
-
self._move( "previousPage", event );
|
5023 |
-
break;
|
5024 |
-
case keyCode.PAGE_DOWN:
|
5025 |
-
self._move( "nextPage", event );
|
5026 |
-
break;
|
5027 |
-
case keyCode.UP:
|
5028 |
-
self._move( "previous", event );
|
5029 |
-
// prevent moving cursor to beginning of text field in some browsers
|
5030 |
-
event.preventDefault();
|
5031 |
-
break;
|
5032 |
-
case keyCode.DOWN:
|
5033 |
-
self._move( "next", event );
|
5034 |
-
// prevent moving cursor to end of text field in some browsers
|
5035 |
-
event.preventDefault();
|
5036 |
-
break;
|
5037 |
-
case keyCode.ENTER:
|
5038 |
-
case keyCode.NUMPAD_ENTER:
|
5039 |
-
// when menu is open and has focus
|
5040 |
-
if ( self.menu.active ) {
|
5041 |
-
// #6055 - Opera still allows the keypress to occur
|
5042 |
-
// which causes forms to submit
|
5043 |
-
suppressKeyPress = true;
|
5044 |
-
event.preventDefault();
|
5045 |
-
}
|
5046 |
-
//passthrough - ENTER and TAB both select the current element
|
5047 |
-
case keyCode.TAB:
|
5048 |
-
if ( !self.menu.active ) {
|
5049 |
-
return;
|
5050 |
-
}
|
5051 |
-
self.menu.select( event );
|
5052 |
-
break;
|
5053 |
-
case keyCode.ESCAPE:
|
5054 |
-
self.element.val( self.term );
|
5055 |
-
self.close( event );
|
5056 |
-
break;
|
5057 |
-
default:
|
5058 |
-
// keypress is triggered before the input value is changed
|
5059 |
-
clearTimeout( self.searching );
|
5060 |
-
self.searching = setTimeout(function() {
|
5061 |
-
// only search if the value has changed
|
5062 |
-
if ( self.term != self.element.val() ) {
|
5063 |
-
self.selectedItem = null;
|
5064 |
-
self.search( null, event );
|
5065 |
-
}
|
5066 |
-
}, self.options.delay );
|
5067 |
-
break;
|
5068 |
-
}
|
5069 |
-
})
|
5070 |
-
.bind( "keypress.autocomplete", function( event ) {
|
5071 |
-
if ( suppressKeyPress ) {
|
5072 |
-
suppressKeyPress = false;
|
5073 |
-
event.preventDefault();
|
5074 |
-
}
|
5075 |
-
})
|
5076 |
-
.bind( "focus.autocomplete", function() {
|
5077 |
-
if ( self.options.disabled ) {
|
5078 |
-
return;
|
5079 |
-
}
|
5080 |
-
|
5081 |
-
self.selectedItem = null;
|
5082 |
-
self.previous = self.element.val();
|
5083 |
-
})
|
5084 |
-
.bind( "blur.autocomplete", function( event ) {
|
5085 |
-
if ( self.options.disabled ) {
|
5086 |
-
return;
|
5087 |
-
}
|
5088 |
-
|
5089 |
-
clearTimeout( self.searching );
|
5090 |
-
// clicks on the menu (or a button to trigger a search) will cause a blur event
|
5091 |
-
self.closing = setTimeout(function() {
|
5092 |
-
self.close( event );
|
5093 |
-
self._change( event );
|
5094 |
-
}, 150 );
|
5095 |
-
});
|
5096 |
-
this._initSource();
|
5097 |
-
this.response = function() {
|
5098 |
-
return self._response.apply( self, arguments );
|
5099 |
-
};
|
5100 |
-
this.menu = $( "<ul></ul>" )
|
5101 |
-
.addClass( "ui-autocomplete" )
|
5102 |
-
.appendTo( $( this.options.appendTo || "body", doc )[0] )
|
5103 |
-
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
|
5104 |
-
.mousedown(function( event ) {
|
5105 |
-
// clicking on the scrollbar causes focus to shift to the body
|
5106 |
-
// but we can't detect a mouseup or a click immediately afterward
|
5107 |
-
// so we have to track the next mousedown and close the menu if
|
5108 |
-
// the user clicks somewhere outside of the autocomplete
|
5109 |
-
var menuElement = self.menu.element[ 0 ];
|
5110 |
-
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
|
5111 |
-
setTimeout(function() {
|
5112 |
-
$( document ).one( 'mousedown', function( event ) {
|
5113 |
-
if ( event.target !== self.element[ 0 ] &&
|
5114 |
-
event.target !== menuElement &&
|
5115 |
-
!$.ui.contains( menuElement, event.target ) ) {
|
5116 |
-
self.close();
|
5117 |
-
}
|
5118 |
-
});
|
5119 |
-
}, 1 );
|
5120 |
-
}
|
5121 |
-
|
5122 |
-
// use another timeout to make sure the blur-event-handler on the input was already triggered
|
5123 |
-
setTimeout(function() {
|
5124 |
-
clearTimeout( self.closing );
|
5125 |
-
}, 13);
|
5126 |
-
})
|
5127 |
-
.menu({
|
5128 |
-
focus: function( event, ui ) {
|
5129 |
-
var item = ui.item.data( "item.autocomplete" );
|
5130 |
-
if ( false !== self._trigger( "focus", event, { item: item } ) ) {
|
5131 |
-
// use value to match what will end up in the input, if it was a key event
|
5132 |
-
if ( /^key/.test(event.originalEvent.type) ) {
|
5133 |
-
self.element.val( item.value );
|
5134 |
-
}
|
5135 |
-
}
|
5136 |
-
},
|
5137 |
-
selected: function( event, ui ) {
|
5138 |
-
var item = ui.item.data( "item.autocomplete" ),
|
5139 |
-
previous = self.previous;
|
5140 |
-
|
5141 |
-
// only trigger when focus was lost (click on menu)
|
5142 |
-
if ( self.element[0] !== doc.activeElement ) {
|
5143 |
-
self.element.focus();
|
5144 |
-
self.previous = previous;
|
5145 |
-
// #6109 - IE triggers two focus events and the second
|
5146 |
-
// is asynchronous, so we need to reset the previous
|
5147 |
-
// term synchronously and asynchronously :-(
|
5148 |
-
setTimeout(function() {
|
5149 |
-
self.previous = previous;
|
5150 |
-
self.selectedItem = item;
|
5151 |
-
}, 1);
|
5152 |
-
}
|
5153 |
-
|
5154 |
-
if ( false !== self._trigger( "select", event, { item: item } ) ) {
|
5155 |
-
self.element.val( item.value );
|
5156 |
-
}
|
5157 |
-
// reset the term after the select event
|
5158 |
-
// this allows custom select handling to work properly
|
5159 |
-
self.term = self.element.val();
|
5160 |
-
|
5161 |
-
self.close( event );
|
5162 |
-
self.selectedItem = item;
|
5163 |
-
},
|
5164 |
-
blur: function( event, ui ) {
|
5165 |
-
// don't set the value of the text field if it's already correct
|
5166 |
-
// this prevents moving the cursor unnecessarily
|
5167 |
-
if ( self.menu.element.is(":visible") &&
|
5168 |
-
( self.element.val() !== self.term ) ) {
|
5169 |
-
self.element.val( self.term );
|
5170 |
-
}
|
5171 |
-
}
|
5172 |
-
})
|
5173 |
-
.zIndex( this.element.zIndex() + 1 )
|
5174 |
-
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
|
5175 |
-
.css({ top: 0, left: 0 })
|
5176 |
-
.hide()
|
5177 |
-
.data( "menu" );
|
5178 |
-
if ( $.fn.bgiframe ) {
|
5179 |
-
this.menu.element.bgiframe();
|
5180 |
}
|
5181 |
-
// turning off autocomplete prevents the browser from remembering the
|
5182 |
-
// value when navigating through history, so we re-enable autocomplete
|
5183 |
-
// if the page is unloaded before the widget is destroyed. #7790
|
5184 |
-
self.beforeunloadHandler = function() {
|
5185 |
-
self.element.removeAttr( "autocomplete" );
|
5186 |
-
};
|
5187 |
-
$( window ).bind( "beforeunload", self.beforeunloadHandler );
|
5188 |
-
},
|
5189 |
-
|
5190 |
-
destroy: function() {
|
5191 |
-
this.element
|
5192 |
-
.removeClass( "ui-autocomplete-input" )
|
5193 |
-
.removeAttr( "autocomplete" )
|
5194 |
-
.removeAttr( "role" )
|
5195 |
-
.removeAttr( "aria-autocomplete" )
|
5196 |
-
.removeAttr( "aria-haspopup" );
|
5197 |
-
this.menu.element.remove();
|
5198 |
-
$( window ).unbind( "beforeunload", this.beforeunloadHandler );
|
5199 |
-
$.Widget.prototype.destroy.call( this );
|
5200 |
},
|
5201 |
|
5202 |
-
|
5203 |
-
|
5204 |
-
|
5205 |
-
this._initSource();
|
5206 |
-
}
|
5207 |
-
if ( key === "appendTo" ) {
|
5208 |
-
this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
|
5209 |
-
}
|
5210 |
-
if ( key === "disabled" && value && this.xhr ) {
|
5211 |
-
this.xhr.abort();
|
5212 |
}
|
|
|
5213 |
},
|
5214 |
|
5215 |
-
|
5216 |
-
|
5217 |
-
|
5218 |
-
|
5219 |
-
|
5220 |
-
|
5221 |
-
|
5222 |
-
|
5223 |
-
|
5224 |
-
}
|
5225 |
-
|
5226 |
-
|
5227 |
-
|
5228 |
-
|
5229 |
-
|
5230 |
-
self.xhr = $.ajax({
|
5231 |
-
url: url,
|
5232 |
-
data: request,
|
5233 |
-
dataType: "json",
|
5234 |
-
autocompleteRequest: ++requestIndex,
|
5235 |
-
success: function( data, status ) {
|
5236 |
-
if ( this.autocompleteRequest === requestIndex ) {
|
5237 |
-
response( data );
|
5238 |
-
}
|
5239 |
-
},
|
5240 |
-
error: function() {
|
5241 |
-
if ( this.autocompleteRequest === requestIndex ) {
|
5242 |
-
response( [] );
|
5243 |
-
}
|
5244 |
-
}
|
5245 |
-
});
|
5246 |
-
};
|
5247 |
-
} else {
|
5248 |
-
this.source = this.options.source;
|
5249 |
}
|
|
|
|
|
|
|
|
|
5250 |
},
|
5251 |
|
5252 |
-
|
5253 |
-
|
5254 |
-
|
5255 |
-
// always save the actual value, not the one passed as an argument
|
5256 |
-
this.term = this.element.val();
|
5257 |
|
5258 |
-
if
|
5259 |
-
|
|
|
5260 |
}
|
5261 |
|
5262 |
-
|
5263 |
-
|
5264 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5265 |
}
|
5266 |
|
5267 |
-
|
5268 |
-
},
|
5269 |
|
5270 |
-
|
5271 |
-
|
5272 |
-
|
|
|
5273 |
|
5274 |
-
|
5275 |
-
},
|
5276 |
|
5277 |
-
|
5278 |
-
if (
|
5279 |
-
|
5280 |
-
|
5281 |
-
this._trigger( "open" );
|
5282 |
} else {
|
5283 |
-
|
5284 |
-
|
5285 |
-
|
5286 |
-
|
5287 |
-
|
5288 |
-
|
5289 |
-
|
5290 |
-
|
5291 |
-
|
5292 |
-
|
5293 |
-
|
5294 |
-
|
5295 |
-
|
5296 |
-
|
5297 |
-
|
5298 |
-
|
5299 |
-
|
5300 |
-
_change: function( event ) {
|
5301 |
-
if ( this.previous !== this.element.val() ) {
|
5302 |
-
this._trigger( "change", event, { item: this.selectedItem } );
|
5303 |
}
|
5304 |
-
|
5305 |
|
5306 |
-
|
5307 |
-
// assume all items have the right format when the first item is complete
|
5308 |
-
if ( items.length && items[0].label && items[0].value ) {
|
5309 |
-
return items;
|
5310 |
-
}
|
5311 |
-
return $.map( items, function(item) {
|
5312 |
-
if ( typeof item === "string" ) {
|
5313 |
-
return {
|
5314 |
-
label: item,
|
5315 |
-
value: item
|
5316 |
-
};
|
5317 |
-
}
|
5318 |
-
return $.extend({
|
5319 |
-
label: item.label || item.value,
|
5320 |
-
value: item.value || item.label
|
5321 |
-
}, item );
|
5322 |
-
});
|
5323 |
},
|
5324 |
|
5325 |
-
|
5326 |
-
var
|
5327 |
-
.empty()
|
5328 |
-
.zIndex( this.element.zIndex() + 1 );
|
5329 |
-
this._renderMenu( ul, items );
|
5330 |
-
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
|
5331 |
-
this.menu.deactivate();
|
5332 |
-
this.menu.refresh();
|
5333 |
|
5334 |
-
|
5335 |
-
|
5336 |
-
this._resizeMenu();
|
5337 |
-
ul.position( $.extend({
|
5338 |
-
of: this.element
|
5339 |
-
}, this.options.position ));
|
5340 |
|
5341 |
-
|
5342 |
-
|
|
|
|
|
5343 |
}
|
5344 |
-
},
|
5345 |
|
5346 |
-
|
5347 |
-
|
5348 |
-
ul.outerWidth( Math.max(
|
5349 |
-
// Firefox wraps long text (possibly a rounding bug)
|
5350 |
-
// so we add 1px to avoid the wrapping (#7513)
|
5351 |
-
ul.width( "" ).outerWidth() + 1,
|
5352 |
-
this.element.outerWidth()
|
5353 |
-
) );
|
5354 |
},
|
5355 |
|
5356 |
-
|
5357 |
-
|
5358 |
-
$.each(
|
5359 |
-
|
|
|
|
|
|
|
5360 |
});
|
5361 |
-
|
|
|
|
|
5362 |
|
5363 |
-
|
5364 |
-
|
5365 |
-
.data( "item.autocomplete", item )
|
5366 |
-
.append( $( "<a></a>" ).text( item.label ) )
|
5367 |
-
.appendTo( ul );
|
5368 |
-
},
|
5369 |
|
5370 |
-
|
5371 |
-
|
5372 |
-
|
5373 |
-
|
5374 |
-
|
5375 |
-
if ( this.menu.first() && /^previous/.test(direction) ||
|
5376 |
-
this.menu.last() && /^next/.test(direction) ) {
|
5377 |
-
this.element.val( this.term );
|
5378 |
-
this.menu.deactivate();
|
5379 |
-
return;
|
5380 |
-
}
|
5381 |
-
this.menu[ direction ]( event );
|
5382 |
-
},
|
5383 |
|
5384 |
-
|
5385 |
-
|
|
|
|
|
|
|
|
|
5386 |
}
|
5387 |
-
});
|
5388 |
|
5389 |
-
|
5390 |
-
|
5391 |
-
|
5392 |
-
|
5393 |
-
|
5394 |
-
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
|
5395 |
-
return $.grep( array, function(value) {
|
5396 |
-
return matcher.test( value.label || value.value || value );
|
5397 |
-
});
|
5398 |
}
|
5399 |
-
});
|
5400 |
|
5401 |
-
|
|
|
|
|
|
|
|
|
|
|
5402 |
|
5403 |
-
|
5404 |
-
|
5405 |
-
|
5406 |
-
|
5407 |
-
|
5408 |
-
* as long as you're okay with migrating your code later on. We can help with that, too.
|
5409 |
-
*
|
5410 |
-
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
5411 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
5412 |
-
* http://jquery.org/license
|
5413 |
-
*
|
5414 |
-
* http://docs.jquery.com/UI/Menu
|
5415 |
-
*
|
5416 |
-
* Depends:
|
5417 |
-
* jquery.ui.core.js
|
5418 |
-
* jquery.ui.widget.js
|
5419 |
-
*/
|
5420 |
-
(function($) {
|
5421 |
|
5422 |
-
|
5423 |
-
|
5424 |
-
|
5425 |
-
|
5426 |
-
.addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
|
5427 |
-
.attr({
|
5428 |
-
role: "listbox",
|
5429 |
-
"aria-activedescendant": "ui-active-menuitem"
|
5430 |
-
})
|
5431 |
-
.click(function( event ) {
|
5432 |
-
if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
|
5433 |
-
return;
|
5434 |
-
}
|
5435 |
-
// temporary
|
5436 |
-
event.preventDefault();
|
5437 |
-
self.select( event );
|
5438 |
-
});
|
5439 |
-
this.refresh();
|
5440 |
-
},
|
5441 |
-
|
5442 |
-
refresh: function() {
|
5443 |
-
var self = this;
|
5444 |
-
|
5445 |
-
// don't refresh list items that are already adapted
|
5446 |
-
var items = this.element.children("li:not(.ui-menu-item):has(a)")
|
5447 |
-
.addClass("ui-menu-item")
|
5448 |
-
.attr("role", "menuitem");
|
5449 |
-
|
5450 |
-
items.children("a")
|
5451 |
-
.addClass("ui-corner-all")
|
5452 |
-
.attr("tabindex", -1)
|
5453 |
-
// mouseenter doesn't work with event delegation
|
5454 |
-
.mouseenter(function( event ) {
|
5455 |
-
self.activate( event, $(this).parent() );
|
5456 |
-
})
|
5457 |
-
.mouseleave(function() {
|
5458 |
-
self.deactivate();
|
5459 |
-
});
|
5460 |
-
},
|
5461 |
|
5462 |
-
|
5463 |
-
|
5464 |
-
|
5465 |
-
|
5466 |
-
|
5467 |
-
elementHeight = this.element.height();
|
5468 |
-
if (offset < 0) {
|
5469 |
-
this.element.scrollTop( scroll + offset);
|
5470 |
-
} else if (offset >= elementHeight) {
|
5471 |
-
this.element.scrollTop( scroll + offset - elementHeight + item.height());
|
5472 |
-
}
|
5473 |
-
}
|
5474 |
-
this.active = item.eq(0)
|
5475 |
-
.children("a")
|
5476 |
-
.addClass("ui-state-hover")
|
5477 |
-
.attr("id", "ui-active-menuitem")
|
5478 |
-
.end();
|
5479 |
-
this._trigger("focus", event, { item: item });
|
5480 |
-
},
|
5481 |
|
5482 |
-
|
5483 |
-
if (!this.active) { return; }
|
5484 |
|
5485 |
-
|
5486 |
-
|
5487 |
-
.removeAttr("id");
|
5488 |
-
this._trigger("blur");
|
5489 |
-
this.active = null;
|
5490 |
-
},
|
5491 |
|
5492 |
-
|
5493 |
-
|
5494 |
-
|
|
|
|
|
5495 |
|
5496 |
-
|
5497 |
-
|
5498 |
-
|
|
|
5499 |
|
5500 |
-
|
5501 |
-
|
5502 |
-
|
|
|
5503 |
|
5504 |
-
|
5505 |
-
|
5506 |
-
|
|
|
5507 |
|
5508 |
-
|
5509 |
-
|
5510 |
-
|
5511 |
-
|
5512 |
-
|
5513 |
-
|
5514 |
-
|
5515 |
-
|
5516 |
-
|
5517 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5518 |
}
|
5519 |
-
},
|
5520 |
|
5521 |
-
|
5522 |
-
|
5523 |
-
|
5524 |
-
|
5525 |
-
|
5526 |
-
|
5527 |
-
|
|
|
|
|
|
|
|
|
|
|
5528 |
}
|
5529 |
-
var base = this.active.offset().top,
|
5530 |
-
height = this.element.height(),
|
5531 |
-
result = this.element.children(".ui-menu-item").filter(function() {
|
5532 |
-
var close = $(this).offset().top - base - height + $(this).height();
|
5533 |
-
// TODO improve approximation
|
5534 |
-
return close < 10 && close > -10;
|
5535 |
-
});
|
5536 |
|
5537 |
-
//
|
5538 |
-
|
5539 |
-
|
|
|
|
|
|
|
|
|
5540 |
}
|
5541 |
-
this.activate(event, result);
|
5542 |
-
} else {
|
5543 |
-
this.activate(event, this.element.children(".ui-menu-item")
|
5544 |
-
.filter(!this.active || this.last() ? ":first" : ":last"));
|
5545 |
}
|
|
|
|
|
5546 |
},
|
5547 |
|
5548 |
-
|
5549 |
-
|
5550 |
-
|
5551 |
-
|
5552 |
-
|
5553 |
-
|
5554 |
-
|
|
|
5555 |
}
|
|
|
|
|
5556 |
|
5557 |
-
|
5558 |
-
|
5559 |
-
|
5560 |
-
|
5561 |
-
|
5562 |
-
|
5563 |
-
|
|
|
|
|
|
|
|
|
5564 |
|
5565 |
-
|
5566 |
-
|
5567 |
-
|
|
|
|
|
|
|
|
|
|
|
5568 |
}
|
5569 |
-
|
5570 |
-
|
5571 |
-
this.activate(event, this.element.children(".ui-menu-item")
|
5572 |
-
.filter(!this.active || this.first() ? ":last" : ":first"));
|
5573 |
-
}
|
5574 |
-
},
|
5575 |
|
5576 |
-
|
5577 |
-
|
5578 |
-
|
|
|
5579 |
|
5580 |
-
|
5581 |
-
|
|
|
|
|
|
|
|
|
5582 |
}
|
5583 |
});
|
5584 |
|
5585 |
-
}(
|
5586 |
-
/*
|
5587 |
-
* jQuery UI Button 1.8.17
|
5588 |
-
*
|
5589 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
5590 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
5591 |
-
* http://jquery.org/license
|
5592 |
-
*
|
5593 |
-
* http://docs.jquery.com/UI/Button
|
5594 |
-
*
|
5595 |
-
* Depends:
|
5596 |
-
* jquery.ui.core.js
|
5597 |
-
* jquery.ui.widget.js
|
5598 |
-
*/
|
5599 |
-
(function( $, undefined ) {
|
5600 |
|
5601 |
-
|
5602 |
-
|
5603 |
-
|
5604 |
-
|
5605 |
-
|
5606 |
-
|
5607 |
-
|
5608 |
-
|
5609 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5610 |
},
|
5611 |
-
|
5612 |
-
|
5613 |
-
|
5614 |
-
|
5615 |
-
|
5616 |
-
|
5617 |
-
|
5618 |
-
|
5619 |
-
|
5620 |
-
|
5621 |
-
|
5622 |
-
|
5623 |
-
|
5624 |
-
|
5625 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5626 |
};
|
|
|
5627 |
|
5628 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5629 |
options: {
|
5630 |
-
|
5631 |
-
|
5632 |
-
|
|
|
|
|
|
|
5633 |
icons: {
|
5634 |
-
|
5635 |
-
|
5636 |
-
}
|
|
|
|
|
|
|
|
|
5637 |
},
|
|
|
5638 |
_create: function() {
|
5639 |
-
this.
|
5640 |
-
|
5641 |
-
|
|
|
|
|
5642 |
|
5643 |
-
|
5644 |
-
|
|
|
5645 |
}
|
5646 |
|
5647 |
-
this.
|
5648 |
-
|
|
|
|
|
|
|
|
|
|
|
5649 |
|
5650 |
-
|
5651 |
-
|
5652 |
-
|
5653 |
-
|
5654 |
-
|
|
|
|
|
5655 |
|
5656 |
-
|
5657 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5658 |
}
|
|
|
5659 |
|
5660 |
-
|
5661 |
-
|
5662 |
-
|
|
|
|
|
|
|
5663 |
|
5664 |
-
|
5665 |
-
|
5666 |
-
.attr( "role", "button" )
|
5667 |
-
.bind( "mouseenter.button", function() {
|
5668 |
-
if ( options.disabled ) {
|
5669 |
-
return;
|
5670 |
-
}
|
5671 |
-
$( this ).addClass( "ui-state-hover" );
|
5672 |
-
if ( this === lastActive ) {
|
5673 |
-
$( this ).addClass( "ui-state-active" );
|
5674 |
-
}
|
5675 |
-
})
|
5676 |
-
.bind( "mouseleave.button", function() {
|
5677 |
-
if ( options.disabled ) {
|
5678 |
-
return;
|
5679 |
-
}
|
5680 |
-
$( this ).removeClass( hoverClass );
|
5681 |
-
})
|
5682 |
-
.bind( "click.button", function( event ) {
|
5683 |
-
if ( options.disabled ) {
|
5684 |
-
event.preventDefault();
|
5685 |
-
event.stopImmediatePropagation();
|
5686 |
-
}
|
5687 |
-
});
|
5688 |
|
|
|
5689 |
this.element
|
5690 |
-
.
|
5691 |
-
|
5692 |
-
self.buttonElement.addClass( focusClass );
|
5693 |
-
})
|
5694 |
-
.bind( "blur.button", function() {
|
5695 |
-
self.buttonElement.removeClass( focusClass );
|
5696 |
-
});
|
5697 |
|
5698 |
-
|
5699 |
-
|
5700 |
-
|
5701 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
5702 |
}
|
5703 |
-
self.refresh();
|
5704 |
-
});
|
5705 |
-
// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
|
5706 |
-
// prevents issue where button state changes but checkbox/radio checked state
|
5707 |
-
// does not in Firefox (see ticket #6970)
|
5708 |
-
this.buttonElement
|
5709 |
-
.bind( "mousedown.button", function( event ) {
|
5710 |
-
if ( options.disabled ) {
|
5711 |
-
return;
|
5712 |
-
}
|
5713 |
-
clickDragged = false;
|
5714 |
-
startXPos = event.pageX;
|
5715 |
-
startYPos = event.pageY;
|
5716 |
-
})
|
5717 |
-
.bind( "mouseup.button", function( event ) {
|
5718 |
-
if ( options.disabled ) {
|
5719 |
-
return;
|
5720 |
-
}
|
5721 |
-
if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
|
5722 |
-
clickDragged = true;
|
5723 |
-
}
|
5724 |
});
|
5725 |
-
|
5726 |
|
5727 |
-
|
5728 |
-
|
5729 |
-
|
5730 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5731 |
}
|
5732 |
-
$( this ).toggleClass( "ui-state-active" );
|
5733 |
-
self.buttonElement.attr( "aria-pressed", self.element[0].checked );
|
5734 |
});
|
5735 |
-
|
5736 |
-
|
5737 |
-
|
5738 |
-
|
5739 |
-
}
|
5740 |
-
$( this ).addClass( "ui-state-active" );
|
5741 |
-
self.buttonElement.attr( "aria-pressed", "true" );
|
5742 |
|
5743 |
-
|
5744 |
-
|
5745 |
-
|
5746 |
-
|
5747 |
-
|
5748 |
-
|
5749 |
-
.removeClass( "ui-state-active" )
|
5750 |
-
.attr( "aria-pressed", "false" );
|
5751 |
-
});
|
5752 |
-
} else {
|
5753 |
-
this.buttonElement
|
5754 |
-
.bind( "mousedown.button", function() {
|
5755 |
-
if ( options.disabled ) {
|
5756 |
-
return false;
|
5757 |
-
}
|
5758 |
-
$( this ).addClass( "ui-state-active" );
|
5759 |
-
lastActive = this;
|
5760 |
-
$( document ).one( "mouseup", function() {
|
5761 |
-
lastActive = null;
|
5762 |
-
});
|
5763 |
-
})
|
5764 |
-
.bind( "mouseup.button", function() {
|
5765 |
-
if ( options.disabled ) {
|
5766 |
-
return false;
|
5767 |
-
}
|
5768 |
-
$( this ).removeClass( "ui-state-active" );
|
5769 |
-
})
|
5770 |
-
.bind( "keydown.button", function(event) {
|
5771 |
-
if ( options.disabled ) {
|
5772 |
-
return false;
|
5773 |
-
}
|
5774 |
-
if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
|
5775 |
-
$( this ).addClass( "ui-state-active" );
|
5776 |
-
}
|
5777 |
-
})
|
5778 |
-
.bind( "keyup.button", function() {
|
5779 |
-
$( this ).removeClass( "ui-state-active" );
|
5780 |
-
});
|
5781 |
|
5782 |
-
|
5783 |
-
|
5784 |
-
|
5785 |
-
// TODO pass through original event correctly (just as 2nd argument doesn't work)
|
5786 |
-
$( this ).click();
|
5787 |
-
}
|
5788 |
-
});
|
5789 |
}
|
|
|
5790 |
}
|
5791 |
|
5792 |
-
|
5793 |
-
// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
|
5794 |
-
// be overridden by individual plugins
|
5795 |
-
this._setOption( "disabled", options.disabled );
|
5796 |
-
this._resetButton();
|
5797 |
-
},
|
5798 |
-
|
5799 |
-
_determineButtonType: function() {
|
5800 |
|
5801 |
-
|
5802 |
-
|
5803 |
-
|
5804 |
-
this.type = "radio";
|
5805 |
-
} else if ( this.element.is("input") ) {
|
5806 |
-
this.type = "input";
|
5807 |
-
} else {
|
5808 |
-
this.type = "button";
|
5809 |
}
|
5810 |
|
5811 |
-
if (
|
5812 |
-
|
5813 |
-
|
5814 |
-
|
5815 |
-
labelSelector = "label[for='" + this.element.attr("id") + "']";
|
5816 |
-
this.buttonElement = ancestor.find( labelSelector );
|
5817 |
-
if ( !this.buttonElement.length ) {
|
5818 |
-
ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
|
5819 |
-
this.buttonElement = ancestor.filter( labelSelector );
|
5820 |
-
if ( !this.buttonElement.length ) {
|
5821 |
-
this.buttonElement = ancestor.find( labelSelector );
|
5822 |
-
}
|
5823 |
}
|
5824 |
-
|
5825 |
|
5826 |
-
|
5827 |
-
|
5828 |
-
|
5829 |
-
|
5830 |
-
|
5831 |
-
} else {
|
5832 |
-
this.buttonElement = this.element;
|
5833 |
}
|
5834 |
},
|
5835 |
|
5836 |
-
|
5837 |
-
|
5838 |
-
|
|
|
|
|
5839 |
|
5840 |
-
|
5841 |
-
|
5842 |
-
.
|
5843 |
-
|
5844 |
-
.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
|
5845 |
-
.removeAttr( "role" )
|
5846 |
-
.removeAttr( "aria-pressed" )
|
5847 |
-
.html( this.buttonElement.find(".ui-button-text").html() );
|
5848 |
|
5849 |
-
|
5850 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5851 |
}
|
5852 |
|
5853 |
-
|
|
|
|
|
|
|
|
|
|
|
5854 |
},
|
5855 |
|
5856 |
-
|
5857 |
-
$.
|
5858 |
-
|
5859 |
-
if ( value ) {
|
5860 |
-
this.element.propAttr( "disabled", true );
|
5861 |
-
} else {
|
5862 |
-
this.element.propAttr( "disabled", false );
|
5863 |
-
}
|
5864 |
-
return;
|
5865 |
}
|
5866 |
-
this._resetButton();
|
5867 |
},
|
5868 |
|
5869 |
refresh: function() {
|
5870 |
-
var
|
5871 |
-
|
5872 |
-
|
5873 |
-
|
5874 |
-
if (
|
5875 |
-
|
5876 |
-
|
5877 |
-
|
5878 |
-
|
5879 |
-
|
5880 |
-
|
5881 |
-
|
5882 |
-
|
5883 |
-
|
5884 |
-
|
5885 |
-
|
5886 |
-
|
5887 |
-
if ( this.element.is( ":checked" ) ) {
|
5888 |
-
this.buttonElement
|
5889 |
-
.addClass( "ui-state-active" )
|
5890 |
-
.attr( "aria-pressed", "true" );
|
5891 |
} else {
|
5892 |
-
this.
|
5893 |
-
.removeClass( "ui-state-active" )
|
5894 |
-
.attr( "aria-pressed", "false" );
|
5895 |
}
|
|
|
|
|
|
|
|
|
5896 |
}
|
5897 |
-
},
|
5898 |
|
5899 |
-
|
5900 |
-
if ( this.type === "input" ) {
|
5901 |
-
if ( this.options.label ) {
|
5902 |
-
this.element.val( this.options.label );
|
5903 |
-
}
|
5904 |
-
return;
|
5905 |
-
}
|
5906 |
-
var buttonElement = this.buttonElement.removeClass( typeClasses ),
|
5907 |
-
buttonText = $( "<span></span>", this.element[0].ownerDocument )
|
5908 |
-
.addClass( "ui-button-text" )
|
5909 |
-
.html( this.options.label )
|
5910 |
-
.appendTo( buttonElement.empty() )
|
5911 |
-
.text(),
|
5912 |
-
icons = this.options.icons,
|
5913 |
-
multipleIcons = icons.primary && icons.secondary,
|
5914 |
-
buttonClasses = [];
|
5915 |
|
5916 |
-
|
5917 |
-
|
5918 |
-
buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
|
5919 |
-
}
|
5920 |
|
5921 |
-
|
5922 |
-
|
5923 |
-
|
5924 |
|
5925 |
-
|
5926 |
-
|
5927 |
-
|
|
|
|
|
5928 |
|
5929 |
-
|
5930 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5931 |
|
5932 |
-
|
5933 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5934 |
}
|
5935 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5936 |
} else {
|
5937 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5938 |
}
|
5939 |
-
buttonElement.addClass( buttonClasses.join( " " ) );
|
5940 |
-
}
|
5941 |
-
});
|
5942 |
|
5943 |
-
|
5944 |
-
|
5945 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5946 |
},
|
5947 |
|
5948 |
-
|
5949 |
-
this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5950 |
},
|
5951 |
-
|
5952 |
-
|
5953 |
-
this.
|
5954 |
},
|
5955 |
|
5956 |
-
|
5957 |
-
|
5958 |
-
|
|
|
|
|
|
|
|
|
|
|
5959 |
}
|
5960 |
|
5961 |
-
|
|
|
|
|
|
|
|
|
5962 |
},
|
5963 |
-
|
5964 |
-
refresh: function() {
|
5965 |
-
var rtl = this.element.css( "direction" ) === "rtl";
|
5966 |
-
|
5967 |
-
this.buttons = this.element.find( this.options.items )
|
5968 |
-
.filter( ":ui-button" )
|
5969 |
-
.button( "refresh" )
|
5970 |
-
.end()
|
5971 |
-
.not( ":ui-button" )
|
5972 |
-
.button()
|
5973 |
-
.end()
|
5974 |
-
.map(function() {
|
5975 |
-
return $( this ).button( "widget" )[ 0 ];
|
5976 |
-
})
|
5977 |
-
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
|
5978 |
-
.filter( ":first" )
|
5979 |
-
.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
|
5980 |
-
.end()
|
5981 |
-
.filter( ":last" )
|
5982 |
-
.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
|
5983 |
-
.end()
|
5984 |
-
.end();
|
5985 |
-
},
|
5986 |
-
|
5987 |
-
destroy: function() {
|
5988 |
-
this.element.removeClass( "ui-buttonset" );
|
5989 |
-
this.buttons
|
5990 |
-
.map(function() {
|
5991 |
-
return $( this ).button( "widget" )[ 0 ];
|
5992 |
-
})
|
5993 |
-
.removeClass( "ui-corner-left ui-corner-right" )
|
5994 |
-
.end()
|
5995 |
-
.button( "destroy" );
|
5996 |
-
|
5997 |
-
$.Widget.prototype.destroy.call( this );
|
5998 |
-
}
|
5999 |
-
});
|
6000 |
-
|
6001 |
-
}( jQuery ) );
|
6002 |
-
/*
|
6003 |
-
* jQuery UI Dialog 1.8.17
|
6004 |
-
*
|
6005 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
6006 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6007 |
-
* http://jquery.org/license
|
6008 |
-
*
|
6009 |
-
* http://docs.jquery.com/UI/Dialog
|
6010 |
-
*
|
6011 |
-
* Depends:
|
6012 |
-
* jquery.ui.core.js
|
6013 |
-
* jquery.ui.widget.js
|
6014 |
-
* jquery.ui.button.js
|
6015 |
-
* jquery.ui.draggable.js
|
6016 |
-
* jquery.ui.mouse.js
|
6017 |
-
* jquery.ui.position.js
|
6018 |
-
* jquery.ui.resizable.js
|
6019 |
-
*/
|
6020 |
-
(function( $, undefined ) {
|
6021 |
|
6022 |
-
|
6023 |
-
|
6024 |
-
|
6025 |
-
|
6026 |
-
|
6027 |
-
|
6028 |
-
|
6029 |
-
|
6030 |
-
|
6031 |
-
|
6032 |
-
|
6033 |
-
|
6034 |
-
|
6035 |
-
|
6036 |
-
resizableRelatedOptions = {
|
6037 |
-
maxHeight: true,
|
6038 |
-
maxWidth: true,
|
6039 |
-
minHeight: true,
|
6040 |
-
minWidth: true
|
6041 |
-
},
|
6042 |
-
// support for jQuery 1.3.2 - handle common attrFn methods for dialog
|
6043 |
-
attrFn = $.attrFn || {
|
6044 |
-
val: true,
|
6045 |
-
css: true,
|
6046 |
-
html: true,
|
6047 |
-
text: true,
|
6048 |
-
data: true,
|
6049 |
-
width: true,
|
6050 |
-
height: true,
|
6051 |
-
offset: true,
|
6052 |
-
click: true
|
6053 |
-
};
|
6054 |
|
6055 |
-
|
6056 |
-
options: {
|
6057 |
-
autoOpen: true,
|
6058 |
-
buttons: {},
|
6059 |
-
closeOnEscape: true,
|
6060 |
-
closeText: 'close',
|
6061 |
-
dialogClass: '',
|
6062 |
-
draggable: true,
|
6063 |
-
hide: null,
|
6064 |
-
height: 'auto',
|
6065 |
-
maxHeight: false,
|
6066 |
-
maxWidth: false,
|
6067 |
-
minHeight: 150,
|
6068 |
-
minWidth: 150,
|
6069 |
-
modal: false,
|
6070 |
-
position: {
|
6071 |
-
my: 'center',
|
6072 |
-
at: 'center',
|
6073 |
-
collision: 'fit',
|
6074 |
-
// ensure that the titlebar is never outside the document
|
6075 |
-
using: function(pos) {
|
6076 |
-
var topOffset = $(this).css(pos).offset().top;
|
6077 |
-
if (topOffset < 0) {
|
6078 |
-
$(this).css('top', pos.top - topOffset);
|
6079 |
-
}
|
6080 |
-
}
|
6081 |
-
},
|
6082 |
-
resizable: true,
|
6083 |
-
show: null,
|
6084 |
-
stack: true,
|
6085 |
-
title: '',
|
6086 |
-
width: 300,
|
6087 |
-
zIndex: 1000
|
6088 |
-
},
|
6089 |
|
6090 |
-
|
6091 |
-
|
6092 |
-
|
6093 |
-
|
6094 |
-
|
|
|
6095 |
}
|
6096 |
|
6097 |
-
|
6098 |
-
var self = this,
|
6099 |
-
options = self.options,
|
6100 |
-
|
6101 |
-
title = options.title || ' ',
|
6102 |
-
titleId = $.ui.dialog.getTitleId(self.element),
|
6103 |
-
|
6104 |
-
uiDialog = (self.uiDialog = $('<div></div>'))
|
6105 |
-
.appendTo(document.body)
|
6106 |
-
.hide()
|
6107 |
-
.addClass(uiDialogClasses + options.dialogClass)
|
6108 |
-
.css({
|
6109 |
-
zIndex: options.zIndex
|
6110 |
-
})
|
6111 |
-
// setting tabIndex makes the div focusable
|
6112 |
-
// setting outline to 0 prevents a border on focus in Mozilla
|
6113 |
-
.attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
|
6114 |
-
if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
|
6115 |
-
event.keyCode === $.ui.keyCode.ESCAPE) {
|
6116 |
-
|
6117 |
-
self.close(event);
|
6118 |
-
event.preventDefault();
|
6119 |
-
}
|
6120 |
-
})
|
6121 |
-
.attr({
|
6122 |
-
role: 'dialog',
|
6123 |
-
'aria-labelledby': titleId
|
6124 |
-
})
|
6125 |
-
.mousedown(function(event) {
|
6126 |
-
self.moveToTop(false, event);
|
6127 |
-
}),
|
6128 |
-
|
6129 |
-
uiDialogContent = self.element
|
6130 |
-
.show()
|
6131 |
-
.removeAttr('title')
|
6132 |
-
.addClass(
|
6133 |
-
'ui-dialog-content ' +
|
6134 |
-
'ui-widget-content')
|
6135 |
-
.appendTo(uiDialog),
|
6136 |
-
|
6137 |
-
uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
|
6138 |
-
.addClass(
|
6139 |
-
'ui-dialog-titlebar ' +
|
6140 |
-
'ui-widget-header ' +
|
6141 |
-
'ui-corner-all ' +
|
6142 |
-
'ui-helper-clearfix'
|
6143 |
-
)
|
6144 |
-
.prependTo(uiDialog),
|
6145 |
-
|
6146 |
-
uiDialogTitlebarClose = $('<a href="#"></a>')
|
6147 |
-
.addClass(
|
6148 |
-
'ui-dialog-titlebar-close ' +
|
6149 |
-
'ui-corner-all'
|
6150 |
-
)
|
6151 |
-
.attr('role', 'button')
|
6152 |
-
.hover(
|
6153 |
-
function() {
|
6154 |
-
uiDialogTitlebarClose.addClass('ui-state-hover');
|
6155 |
-
},
|
6156 |
-
function() {
|
6157 |
-
uiDialogTitlebarClose.removeClass('ui-state-hover');
|
6158 |
-
}
|
6159 |
-
)
|
6160 |
-
.focus(function() {
|
6161 |
-
uiDialogTitlebarClose.addClass('ui-state-focus');
|
6162 |
-
})
|
6163 |
-
.blur(function() {
|
6164 |
-
uiDialogTitlebarClose.removeClass('ui-state-focus');
|
6165 |
-
})
|
6166 |
-
.click(function(event) {
|
6167 |
-
self.close(event);
|
6168 |
-
return false;
|
6169 |
-
})
|
6170 |
-
.appendTo(uiDialogTitlebar),
|
6171 |
-
|
6172 |
-
uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
|
6173 |
-
.addClass(
|
6174 |
-
'ui-icon ' +
|
6175 |
-
'ui-icon-closethick'
|
6176 |
-
)
|
6177 |
-
.text(options.closeText)
|
6178 |
-
.appendTo(uiDialogTitlebarClose),
|
6179 |
-
|
6180 |
-
uiDialogTitle = $('<span></span>')
|
6181 |
-
.addClass('ui-dialog-title')
|
6182 |
-
.attr('id', titleId)
|
6183 |
-
.html(title)
|
6184 |
-
.prependTo(uiDialogTitlebar);
|
6185 |
-
|
6186 |
-
//handling of deprecated beforeclose (vs beforeClose) option
|
6187 |
-
//Ticket #4669 http://dev.jqueryui.com/ticket/4669
|
6188 |
-
//TODO: remove in 1.9pre
|
6189 |
-
if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
|
6190 |
-
options.beforeClose = options.beforeclose;
|
6191 |
-
}
|
6192 |
|
6193 |
-
|
|
|
|
|
|
|
6194 |
|
6195 |
-
|
6196 |
-
|
6197 |
-
|
6198 |
-
if (options.
|
6199 |
-
|
|
|
|
|
6200 |
}
|
6201 |
|
6202 |
-
|
6203 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6204 |
|
6205 |
-
|
6206 |
-
|
|
|
6207 |
}
|
6208 |
},
|
6209 |
|
6210 |
-
|
6211 |
-
|
6212 |
-
this.
|
6213 |
-
}
|
6214 |
-
},
|
6215 |
|
6216 |
-
|
6217 |
-
|
6218 |
-
|
6219 |
-
|
6220 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
6221 |
}
|
6222 |
-
self.uiDialog.hide();
|
6223 |
-
self.element
|
6224 |
-
.unbind('.dialog')
|
6225 |
-
.removeData('dialog')
|
6226 |
-
.removeClass('ui-dialog-content ui-widget-content')
|
6227 |
-
.hide().appendTo('body');
|
6228 |
-
self.uiDialog.remove();
|
6229 |
|
6230 |
-
|
6231 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6232 |
}
|
6233 |
|
6234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6235 |
},
|
6236 |
|
6237 |
-
|
6238 |
-
|
6239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6240 |
|
6241 |
-
|
6242 |
-
|
6243 |
-
maxZ, thisZ;
|
6244 |
-
|
6245 |
-
if (false === self._trigger('beforeClose', event)) {
|
6246 |
-
return;
|
6247 |
}
|
6248 |
-
|
6249 |
-
|
6250 |
-
self.overlay.destroy();
|
6251 |
}
|
6252 |
-
|
|
|
|
|
6253 |
|
6254 |
-
|
6255 |
-
|
6256 |
-
|
6257 |
-
|
6258 |
-
|
6259 |
-
});
|
6260 |
-
} else {
|
6261 |
-
self.uiDialog.hide();
|
6262 |
-
self._trigger('close', event);
|
6263 |
}
|
6264 |
|
6265 |
-
|
6266 |
-
|
6267 |
-
|
6268 |
-
|
6269 |
-
|
6270 |
-
|
6271 |
-
|
6272 |
-
|
6273 |
-
|
6274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6275 |
}
|
6276 |
}
|
6277 |
});
|
6278 |
-
$.ui.dialog.maxZ = maxZ;
|
6279 |
-
}
|
6280 |
-
|
6281 |
-
return self;
|
6282 |
},
|
6283 |
|
6284 |
-
|
6285 |
-
|
6286 |
-
},
|
6287 |
|
6288 |
-
|
6289 |
-
|
6290 |
-
|
6291 |
-
|
6292 |
-
|
6293 |
-
saveScroll;
|
6294 |
|
6295 |
-
|
6296 |
-
|
6297 |
-
|
6298 |
}
|
6299 |
|
6300 |
-
|
6301 |
-
|
6302 |
-
|
6303 |
-
if (self.overlay) {
|
6304 |
-
$.ui.dialog.maxZ += 1;
|
6305 |
-
self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
|
6306 |
-
}
|
6307 |
|
6308 |
-
|
6309 |
-
// http://ui.jquery.com/bugs/ticket/3193
|
6310 |
-
saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
|
6311 |
-
$.ui.dialog.maxZ += 1;
|
6312 |
-
self.uiDialog.css('z-index', $.ui.dialog.maxZ);
|
6313 |
-
self.element.attr(saveScroll);
|
6314 |
-
self._trigger('focus', event);
|
6315 |
|
6316 |
-
|
6317 |
-
},
|
6318 |
|
6319 |
-
|
6320 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6321 |
|
6322 |
-
|
6323 |
-
|
6324 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
6325 |
|
6326 |
-
|
6327 |
-
self._size();
|
6328 |
-
self._position(options.position);
|
6329 |
-
uiDialog.show(options.show);
|
6330 |
-
self.moveToTop(true);
|
6331 |
|
6332 |
-
|
6333 |
-
|
6334 |
-
|
6335 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6336 |
return;
|
6337 |
}
|
6338 |
|
6339 |
-
|
6340 |
-
|
6341 |
-
|
6342 |
-
|
6343 |
-
|
6344 |
-
|
6345 |
-
|
6346 |
-
|
6347 |
-
|
6348 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6349 |
}
|
6350 |
-
});
|
6351 |
-
}
|
6352 |
|
6353 |
-
|
6354 |
-
|
6355 |
-
|
6356 |
-
|
6357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6358 |
|
6359 |
-
|
6360 |
-
|
|
|
|
|
|
|
6361 |
|
6362 |
-
|
6363 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6364 |
|
6365 |
-
|
6366 |
-
|
6367 |
-
|
6368 |
-
|
6369 |
-
.addClass(
|
6370 |
-
'ui-dialog-buttonpane ' +
|
6371 |
-
'ui-widget-content ' +
|
6372 |
-
'ui-helper-clearfix'
|
6373 |
-
),
|
6374 |
-
uiButtonSet = $( "<div></div>" )
|
6375 |
-
.addClass( "ui-dialog-buttonset" )
|
6376 |
-
.appendTo( uiDialogButtonPane );
|
6377 |
|
6378 |
-
|
6379 |
-
|
|
|
|
|
|
|
|
|
6380 |
|
6381 |
-
|
6382 |
-
|
6383 |
-
|
6384 |
-
|
6385 |
-
|
6386 |
-
|
6387 |
-
|
6388 |
-
|
6389 |
-
|
6390 |
-
|
6391 |
-
|
6392 |
-
|
6393 |
-
|
6394 |
-
|
6395 |
-
|
6396 |
-
|
6397 |
-
|
6398 |
-
|
6399 |
-
|
6400 |
-
|
6401 |
-
|
6402 |
-
|
6403 |
-
|
6404 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6405 |
}
|
6406 |
-
});
|
6407 |
-
if ($.fn.button) {
|
6408 |
-
button.button();
|
6409 |
}
|
6410 |
-
});
|
6411 |
-
uiDialogButtonPane.appendTo(self.uiDialog);
|
6412 |
-
}
|
6413 |
-
},
|
6414 |
|
6415 |
-
|
6416 |
-
|
6417 |
-
|
6418 |
-
|
6419 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6420 |
|
6421 |
-
|
6422 |
-
|
6423 |
-
|
6424 |
-
|
6425 |
-
|
6426 |
-
|
6427 |
|
6428 |
-
|
6429 |
-
|
6430 |
-
handle: '.ui-dialog-titlebar',
|
6431 |
-
containment: 'document',
|
6432 |
-
start: function(event, ui) {
|
6433 |
-
heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
|
6434 |
-
$(this).height($(this).height()).addClass("ui-dialog-dragging");
|
6435 |
-
self._trigger('dragStart', event, filteredUi(ui));
|
6436 |
-
},
|
6437 |
-
drag: function(event, ui) {
|
6438 |
-
self._trigger('drag', event, filteredUi(ui));
|
6439 |
-
},
|
6440 |
-
stop: function(event, ui) {
|
6441 |
-
options.position = [ui.position.left - doc.scrollLeft(),
|
6442 |
-
ui.position.top - doc.scrollTop()];
|
6443 |
-
$(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
|
6444 |
-
self._trigger('dragStop', event, filteredUi(ui));
|
6445 |
-
$.ui.dialog.overlay.resize();
|
6446 |
}
|
6447 |
});
|
6448 |
-
},
|
6449 |
-
|
6450 |
-
_makeResizable: function(handles) {
|
6451 |
-
handles = (handles === undefined ? this.options.resizable : handles);
|
6452 |
-
var self = this,
|
6453 |
-
options = self.options,
|
6454 |
-
// .ui-resizable has position: relative defined in the stylesheet
|
6455 |
-
// but dialogs have to use absolute or fixed positioning
|
6456 |
-
position = self.uiDialog.css('position'),
|
6457 |
-
resizeHandles = (typeof handles === 'string' ?
|
6458 |
-
handles :
|
6459 |
-
'n,e,s,w,se,sw,ne,nw'
|
6460 |
-
);
|
6461 |
|
6462 |
-
|
6463 |
-
|
6464 |
-
|
6465 |
-
|
6466 |
-
|
6467 |
-
|
6468 |
-
};
|
6469 |
-
}
|
6470 |
|
6471 |
-
|
6472 |
-
|
6473 |
-
|
6474 |
-
|
6475 |
-
|
6476 |
-
|
6477 |
-
minWidth: options.minWidth,
|
6478 |
-
minHeight: self._minHeight(),
|
6479 |
-
handles: resizeHandles,
|
6480 |
-
start: function(event, ui) {
|
6481 |
-
$(this).addClass("ui-dialog-resizing");
|
6482 |
-
self._trigger('resizeStart', event, filteredUi(ui));
|
6483 |
-
},
|
6484 |
-
resize: function(event, ui) {
|
6485 |
-
self._trigger('resize', event, filteredUi(ui));
|
6486 |
-
},
|
6487 |
-
stop: function(event, ui) {
|
6488 |
-
$(this).removeClass("ui-dialog-resizing");
|
6489 |
-
options.height = $(this).height();
|
6490 |
-
options.width = $(this).width();
|
6491 |
-
self._trigger('resizeStop', event, filteredUi(ui));
|
6492 |
-
$.ui.dialog.overlay.resize();
|
6493 |
}
|
6494 |
-
})
|
6495 |
-
.css('position', position)
|
6496 |
-
.find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
|
6497 |
},
|
6498 |
|
6499 |
-
|
6500 |
-
|
6501 |
-
|
6502 |
-
|
6503 |
-
|
6504 |
-
|
6505 |
-
|
6506 |
-
}
|
6507 |
},
|
6508 |
|
6509 |
-
|
6510 |
-
|
6511 |
-
|
6512 |
-
|
6513 |
-
|
6514 |
-
if (position) {
|
6515 |
-
// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
|
6516 |
-
// if (typeof position == 'string' || $.isArray(position)) {
|
6517 |
-
// myAt = $.isArray(position) ? position : position.split(' ');
|
6518 |
-
|
6519 |
-
if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
|
6520 |
-
myAt = position.split ? position.split(' ') : [position[0], position[1]];
|
6521 |
-
if (myAt.length === 1) {
|
6522 |
-
myAt[1] = myAt[0];
|
6523 |
-
}
|
6524 |
-
|
6525 |
-
$.each(['left', 'top'], function(i, offsetPosition) {
|
6526 |
-
if (+myAt[i] === myAt[i]) {
|
6527 |
-
offset[i] = myAt[i];
|
6528 |
-
myAt[i] = offsetPosition;
|
6529 |
-
}
|
6530 |
-
});
|
6531 |
-
|
6532 |
-
position = {
|
6533 |
-
my: myAt.join(" "),
|
6534 |
-
at: myAt.join(" "),
|
6535 |
-
offset: offset.join(" ")
|
6536 |
-
};
|
6537 |
-
}
|
6538 |
-
|
6539 |
-
position = $.extend({}, $.ui.dialog.prototype.options.position, position);
|
6540 |
-
} else {
|
6541 |
-
position = $.ui.dialog.prototype.options.position;
|
6542 |
}
|
6543 |
-
|
6544 |
-
|
6545 |
-
isVisible = this.uiDialog.is(':visible');
|
6546 |
-
if (!isVisible) {
|
6547 |
-
this.uiDialog.show();
|
6548 |
}
|
6549 |
-
this.
|
6550 |
-
|
6551 |
-
.css({ top: 0, left: 0 })
|
6552 |
-
.position($.extend({ of: window }, position));
|
6553 |
-
if (!isVisible) {
|
6554 |
-
this.uiDialog.hide();
|
6555 |
}
|
6556 |
},
|
6557 |
|
6558 |
-
|
6559 |
-
var
|
6560 |
-
resizableOptions = {},
|
6561 |
-
resize = false;
|
6562 |
-
|
6563 |
-
$.each( options, function( key, value ) {
|
6564 |
-
self._setOption( key, value );
|
6565 |
-
|
6566 |
-
if ( key in sizeRelatedOptions ) {
|
6567 |
-
resize = true;
|
6568 |
-
}
|
6569 |
-
if ( key in resizableRelatedOptions ) {
|
6570 |
-
resizableOptions[ key ] = value;
|
6571 |
-
}
|
6572 |
-
});
|
6573 |
|
6574 |
-
if (
|
6575 |
-
|
|
|
|
|
6576 |
}
|
6577 |
-
|
6578 |
-
|
|
|
6579 |
}
|
6580 |
-
},
|
6581 |
|
6582 |
-
|
6583 |
-
|
6584 |
-
|
6585 |
-
|
6586 |
-
switch (key) {
|
6587 |
-
//handling of deprecated beforeclose (vs beforeClose) option
|
6588 |
-
//Ticket #4669 http://dev.jqueryui.com/ticket/4669
|
6589 |
-
//TODO: remove in 1.9pre
|
6590 |
-
case "beforeclose":
|
6591 |
-
key = "beforeClose";
|
6592 |
-
break;
|
6593 |
-
case "buttons":
|
6594 |
-
self._createButtons(value);
|
6595 |
-
break;
|
6596 |
-
case "closeText":
|
6597 |
-
// ensure that we always pass a string
|
6598 |
-
self.uiDialogTitlebarCloseText.text("" + value);
|
6599 |
-
break;
|
6600 |
-
case "dialogClass":
|
6601 |
-
uiDialog
|
6602 |
-
.removeClass(self.options.dialogClass)
|
6603 |
-
.addClass(uiDialogClasses + value);
|
6604 |
-
break;
|
6605 |
-
case "disabled":
|
6606 |
-
if (value) {
|
6607 |
-
uiDialog.addClass('ui-dialog-disabled');
|
6608 |
-
} else {
|
6609 |
-
uiDialog.removeClass('ui-dialog-disabled');
|
6610 |
-
}
|
6611 |
-
break;
|
6612 |
-
case "draggable":
|
6613 |
-
var isDraggable = uiDialog.is( ":data(draggable)" );
|
6614 |
-
if ( isDraggable && !value ) {
|
6615 |
-
uiDialog.draggable( "destroy" );
|
6616 |
-
}
|
6617 |
-
|
6618 |
-
if ( !isDraggable && value ) {
|
6619 |
-
self._makeDraggable();
|
6620 |
-
}
|
6621 |
-
break;
|
6622 |
-
case "position":
|
6623 |
-
self._position(value);
|
6624 |
-
break;
|
6625 |
-
case "resizable":
|
6626 |
-
// currently resizable, becoming non-resizable
|
6627 |
-
var isResizable = uiDialog.is( ":data(resizable)" );
|
6628 |
-
if (isResizable && !value) {
|
6629 |
-
uiDialog.resizable('destroy');
|
6630 |
-
}
|
6631 |
|
6632 |
-
|
6633 |
-
|
6634 |
-
uiDialog.resizable('option', 'handles', value);
|
6635 |
-
}
|
6636 |
|
6637 |
-
|
6638 |
-
|
6639 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6640 |
}
|
6641 |
-
|
6642 |
-
|
6643 |
-
|
6644 |
-
|
6645 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6646 |
}
|
6647 |
-
|
6648 |
-
$.Widget.prototype._setOption.apply(self, arguments);
|
6649 |
},
|
6650 |
|
6651 |
-
|
6652 |
-
|
6653 |
-
|
6654 |
-
|
6655 |
-
|
6656 |
-
|
6657 |
-
|
6658 |
-
|
|
|
|
|
6659 |
|
6660 |
-
|
6661 |
-
this.
|
6662 |
-
width: 'auto',
|
6663 |
-
minHeight: 0,
|
6664 |
-
height: 0
|
6665 |
-
});
|
6666 |
|
6667 |
-
|
6668 |
-
|
6669 |
-
}
|
6670 |
|
6671 |
-
|
6672 |
-
|
6673 |
-
nonContentHeight = this.uiDialog.css({
|
6674 |
-
height: 'auto',
|
6675 |
-
width: options.width
|
6676 |
-
})
|
6677 |
-
.height();
|
6678 |
-
minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
|
6679 |
-
|
6680 |
-
if ( options.height === "auto" ) {
|
6681 |
-
// only needed for IE6 support
|
6682 |
-
if ( $.support.minHeight ) {
|
6683 |
-
this.element.css({
|
6684 |
-
minHeight: minContentHeight,
|
6685 |
-
height: "auto"
|
6686 |
-
});
|
6687 |
-
} else {
|
6688 |
-
this.uiDialog.show();
|
6689 |
-
var autoHeight = this.element.css( "height", "auto" ).height();
|
6690 |
-
if ( !isVisible ) {
|
6691 |
-
this.uiDialog.hide();
|
6692 |
-
}
|
6693 |
-
this.element.height( Math.max( autoHeight, minContentHeight ) );
|
6694 |
-
}
|
6695 |
-
} else {
|
6696 |
-
this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
|
6697 |
}
|
6698 |
|
6699 |
-
if (this.
|
6700 |
-
|
6701 |
}
|
6702 |
-
}
|
6703 |
-
});
|
6704 |
|
6705 |
-
|
6706 |
-
|
6707 |
|
6708 |
-
|
6709 |
-
|
|
|
|
|
6710 |
|
6711 |
-
|
6712 |
-
var id = $el.attr('id');
|
6713 |
-
if (!id) {
|
6714 |
-
this.uuid += 1;
|
6715 |
-
id = this.uuid;
|
6716 |
-
}
|
6717 |
-
return 'ui-dialog-title-' + id;
|
6718 |
},
|
6719 |
|
6720 |
-
|
6721 |
-
|
6722 |
-
|
6723 |
-
});
|
6724 |
|
6725 |
-
|
6726 |
-
|
6727 |
-
|
6728 |
-
|
6729 |
-
maxZ: 0,
|
6730 |
-
events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
|
6731 |
-
function(event) { return event + '.dialog-overlay'; }).join(' '),
|
6732 |
-
create: function(dialog) {
|
6733 |
-
if (this.instances.length === 0) {
|
6734 |
-
// prevent use of anchors and inputs
|
6735 |
-
// we use a setTimeout in case the overlay is created from an
|
6736 |
-
// event that we're going to be cancelling (see #2804)
|
6737 |
-
setTimeout(function() {
|
6738 |
-
// handle $(el).dialog().dialog('close') (see #4065)
|
6739 |
-
if ($.ui.dialog.overlay.instances.length) {
|
6740 |
-
$(document).bind($.ui.dialog.overlay.events, function(event) {
|
6741 |
-
// stop events if the z-index of the target is < the z-index of the overlay
|
6742 |
-
// we cannot return true when we don't want to cancel the event (#3523)
|
6743 |
-
if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
|
6744 |
-
return false;
|
6745 |
-
}
|
6746 |
-
});
|
6747 |
-
}
|
6748 |
-
}, 1);
|
6749 |
|
6750 |
-
|
6751 |
-
|
6752 |
-
|
6753 |
-
|
6754 |
-
|
6755 |
-
|
6756 |
-
event.preventDefault();
|
6757 |
-
}
|
6758 |
-
});
|
6759 |
|
6760 |
-
|
6761 |
-
|
|
|
6762 |
}
|
6763 |
-
|
6764 |
-
|
6765 |
-
.
|
6766 |
-
.
|
6767 |
-
|
6768 |
-
|
6769 |
-
|
6770 |
-
|
6771 |
-
if ($.fn.bgiframe) {
|
6772 |
-
$el.bgiframe();
|
6773 |
}
|
|
|
6774 |
|
6775 |
-
|
6776 |
-
|
|
|
6777 |
},
|
6778 |
|
6779 |
-
|
6780 |
-
|
6781 |
-
|
6782 |
-
this.
|
|
|
|
|
6783 |
}
|
|
|
6784 |
|
6785 |
-
|
6786 |
-
|
|
|
6787 |
}
|
|
|
6788 |
|
6789 |
-
|
6790 |
-
|
6791 |
-
|
6792 |
-
|
6793 |
-
|
6794 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6795 |
});
|
6796 |
-
this.maxZ = maxZ;
|
6797 |
},
|
6798 |
|
6799 |
-
|
6800 |
-
var
|
6801 |
-
|
6802 |
-
|
6803 |
-
|
6804 |
-
scrollHeight = Math.max(
|
6805 |
-
document.documentElement.scrollHeight,
|
6806 |
-
document.body.scrollHeight
|
6807 |
-
);
|
6808 |
-
offsetHeight = Math.max(
|
6809 |
-
document.documentElement.offsetHeight,
|
6810 |
-
document.body.offsetHeight
|
6811 |
-
);
|
6812 |
|
6813 |
-
|
6814 |
-
|
6815 |
-
|
6816 |
-
|
6817 |
-
|
6818 |
-
|
6819 |
-
|
6820 |
-
|
|
|
6821 |
}
|
6822 |
},
|
6823 |
|
6824 |
-
|
6825 |
-
var
|
6826 |
-
|
6827 |
-
|
6828 |
-
|
6829 |
-
|
6830 |
-
|
6831 |
-
|
6832 |
-
);
|
6833 |
-
offsetWidth = Math.max(
|
6834 |
-
document.documentElement.offsetWidth,
|
6835 |
-
document.body.offsetWidth
|
6836 |
-
);
|
6837 |
-
|
6838 |
-
if (scrollWidth < offsetWidth) {
|
6839 |
-
return $(window).width() + 'px';
|
6840 |
-
} else {
|
6841 |
-
return scrollWidth + 'px';
|
6842 |
-
}
|
6843 |
-
// handle "good" browsers
|
6844 |
-
} else {
|
6845 |
-
return $(document).width() + 'px';
|
6846 |
-
}
|
6847 |
},
|
6848 |
|
6849 |
-
|
6850 |
-
|
6851 |
-
|
6852 |
-
|
6853 |
-
* dialog back to the left, the document will become narrower,
|
6854 |
-
* so we need to shrink the overlay to the appropriate size.
|
6855 |
-
* This is handled by shrinking the overlay before setting it
|
6856 |
-
* to the full document size.
|
6857 |
-
*/
|
6858 |
-
var $overlays = $([]);
|
6859 |
-
$.each($.ui.dialog.overlay.instances, function() {
|
6860 |
-
$overlays = $overlays.add(this);
|
6861 |
});
|
|
|
6862 |
|
6863 |
-
|
6864 |
-
|
6865 |
-
|
6866 |
-
|
6867 |
-
|
6868 |
-
|
6869 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6870 |
}
|
6871 |
});
|
6872 |
|
6873 |
-
$.extend($.ui.
|
6874 |
-
|
6875 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
6876 |
}
|
6877 |
});
|
6878 |
|
6879 |
-
}(jQuery));
|
6880 |
-
/*
|
6881 |
-
* jQuery UI Slider 1.8.17
|
6882 |
-
*
|
6883 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
6884 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
6885 |
-
* http://jquery.org/license
|
6886 |
-
*
|
6887 |
-
* http://docs.jquery.com/UI/Slider
|
6888 |
-
*
|
6889 |
-
* Depends:
|
6890 |
-
* jquery.ui.core.js
|
6891 |
-
* jquery.ui.mouse.js
|
6892 |
-
* jquery.ui.widget.js
|
6893 |
-
*/
|
6894 |
-
(function( $, undefined ) {
|
6895 |
-
|
6896 |
-
// number of pages in a slider
|
6897 |
-
// (how many times can you page up/down to go through the whole range)
|
6898 |
-
var numPages = 5;
|
6899 |
-
|
6900 |
-
$.widget( "ui.slider", $.ui.mouse, {
|
6901 |
-
|
6902 |
-
widgetEventPrefix: "slide",
|
6903 |
|
|
|
|
|
|
|
|
|
6904 |
options: {
|
6905 |
-
|
6906 |
-
|
6907 |
-
|
6908 |
-
|
6909 |
-
|
6910 |
-
|
6911 |
-
|
6912 |
-
value: 0,
|
6913 |
-
values: null
|
6914 |
},
|
6915 |
|
6916 |
-
|
6917 |
-
var
|
6918 |
-
|
6919 |
-
|
6920 |
-
|
6921 |
-
|
6922 |
-
|
6923 |
-
|
6924 |
-
|
6925 |
-
|
6926 |
-
|
6927 |
-
this.
|
6928 |
-
|
6929 |
-
|
6930 |
|
6931 |
-
|
6932 |
-
.addClass( "ui-slider" +
|
6933 |
-
" ui-slider-" + this.orientation +
|
6934 |
-
" ui-widget" +
|
6935 |
-
" ui-widget-content" +
|
6936 |
-
" ui-corner-all" +
|
6937 |
-
( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
|
6938 |
|
6939 |
-
|
6940 |
|
6941 |
-
|
6942 |
-
|
6943 |
-
|
6944 |
-
|
6945 |
-
|
6946 |
-
|
6947 |
-
|
6948 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6949 |
}
|
|
|
|
|
|
|
6950 |
|
6951 |
-
|
6952 |
-
|
6953 |
-
|
6954 |
-
|
6955 |
-
|
6956 |
-
|
6957 |
-
|
|
|
|
|
|
|
6958 |
}
|
|
|
|
|
|
|
|
|
|
|
6959 |
|
6960 |
-
|
6961 |
-
|
|
|
|
|
6962 |
}
|
6963 |
|
6964 |
-
this.
|
|
|
6965 |
|
6966 |
-
|
|
|
|
|
|
|
|
|
6967 |
|
6968 |
-
|
6969 |
-
.
|
6970 |
-
|
6971 |
-
})
|
6972 |
-
.hover(function() {
|
6973 |
-
if ( !o.disabled ) {
|
6974 |
-
$( this ).addClass( "ui-state-hover" );
|
6975 |
-
}
|
6976 |
-
}, function() {
|
6977 |
-
$( this ).removeClass( "ui-state-hover" );
|
6978 |
-
})
|
6979 |
-
.focus(function() {
|
6980 |
-
if ( !o.disabled ) {
|
6981 |
-
$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
|
6982 |
-
$( this ).addClass( "ui-state-focus" );
|
6983 |
-
} else {
|
6984 |
-
$( this ).blur();
|
6985 |
-
}
|
6986 |
-
})
|
6987 |
-
.blur(function() {
|
6988 |
-
$( this ).removeClass( "ui-state-focus" );
|
6989 |
-
});
|
6990 |
|
6991 |
-
this.
|
6992 |
-
$( this ).data( "index.ui-slider-handle", i );
|
6993 |
-
});
|
6994 |
|
6995 |
-
this.
|
6996 |
-
.
|
6997 |
-
|
6998 |
-
|
6999 |
-
|
7000 |
-
curVal,
|
7001 |
-
newVal,
|
7002 |
-
step;
|
7003 |
-
|
7004 |
-
if ( self.options.disabled ) {
|
7005 |
return;
|
7006 |
}
|
7007 |
-
|
7008 |
-
|
7009 |
-
case $.ui.keyCode.HOME:
|
7010 |
-
case $.ui.keyCode.END:
|
7011 |
-
case $.ui.keyCode.PAGE_UP:
|
7012 |
-
case $.ui.keyCode.PAGE_DOWN:
|
7013 |
-
case $.ui.keyCode.UP:
|
7014 |
-
case $.ui.keyCode.RIGHT:
|
7015 |
-
case $.ui.keyCode.DOWN:
|
7016 |
-
case $.ui.keyCode.LEFT:
|
7017 |
-
ret = false;
|
7018 |
-
if ( !self._keySliding ) {
|
7019 |
-
self._keySliding = true;
|
7020 |
-
$( this ).addClass( "ui-state-active" );
|
7021 |
-
allowed = self._start( event, index );
|
7022 |
-
if ( allowed === false ) {
|
7023 |
-
return;
|
7024 |
-
}
|
7025 |
-
}
|
7026 |
-
break;
|
7027 |
-
}
|
7028 |
-
|
7029 |
-
step = self.options.step;
|
7030 |
-
if ( self.options.values && self.options.values.length ) {
|
7031 |
-
curVal = newVal = self.values( index );
|
7032 |
-
} else {
|
7033 |
-
curVal = newVal = self.value();
|
7034 |
}
|
7035 |
-
|
7036 |
-
|
7037 |
-
|
7038 |
-
|
7039 |
-
break;
|
7040 |
-
case $.ui.keyCode.END:
|
7041 |
-
newVal = self._valueMax();
|
7042 |
-
break;
|
7043 |
-
case $.ui.keyCode.PAGE_UP:
|
7044 |
-
newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
|
7045 |
-
break;
|
7046 |
-
case $.ui.keyCode.PAGE_DOWN:
|
7047 |
-
newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
|
7048 |
-
break;
|
7049 |
-
case $.ui.keyCode.UP:
|
7050 |
-
case $.ui.keyCode.RIGHT:
|
7051 |
-
if ( curVal === self._valueMax() ) {
|
7052 |
-
return;
|
7053 |
-
}
|
7054 |
-
newVal = self._trimAlignValue( curVal + step );
|
7055 |
-
break;
|
7056 |
-
case $.ui.keyCode.DOWN:
|
7057 |
-
case $.ui.keyCode.LEFT:
|
7058 |
-
if ( curVal === self._valueMin() ) {
|
7059 |
-
return;
|
7060 |
-
}
|
7061 |
-
newVal = self._trimAlignValue( curVal - step );
|
7062 |
-
break;
|
7063 |
}
|
7064 |
-
|
7065 |
-
self._slide( event, index, newVal );
|
7066 |
-
|
7067 |
-
return ret;
|
7068 |
-
|
7069 |
})
|
7070 |
-
.
|
7071 |
-
|
7072 |
-
|
7073 |
-
|
7074 |
-
self._keySliding = false;
|
7075 |
-
self._stop( event, index );
|
7076 |
-
self._change( event, index );
|
7077 |
-
$( this ).removeClass( "ui-state-active" );
|
7078 |
}
|
7079 |
-
|
7080 |
});
|
7081 |
|
7082 |
-
this._refreshValue();
|
7083 |
-
|
7084 |
-
this._animateOff = false;
|
7085 |
-
},
|
7086 |
-
|
7087 |
-
destroy: function() {
|
7088 |
-
this.handles.remove();
|
7089 |
-
this.range.remove();
|
7090 |
-
|
7091 |
this.element
|
7092 |
-
.
|
7093 |
-
|
7094 |
-
|
7095 |
-
|
7096 |
-
|
7097 |
-
|
7098 |
-
|
7099 |
-
.removeData( "slider" )
|
7100 |
-
.unbind( ".slider" );
|
7101 |
-
|
7102 |
-
this._mouseDestroy();
|
7103 |
-
|
7104 |
-
return this;
|
7105 |
-
},
|
7106 |
-
|
7107 |
-
_mouseCapture: function( event ) {
|
7108 |
-
var o = this.options,
|
7109 |
-
position,
|
7110 |
-
normValue,
|
7111 |
-
distance,
|
7112 |
-
closestHandle,
|
7113 |
-
self,
|
7114 |
-
index,
|
7115 |
-
allowed,
|
7116 |
-
offset,
|
7117 |
-
mouseOverHandle;
|
7118 |
|
7119 |
-
if (
|
7120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7121 |
}
|
7122 |
|
7123 |
-
this.
|
7124 |
-
|
7125 |
-
|
7126 |
-
|
7127 |
-
|
7128 |
-
|
7129 |
-
|
7130 |
-
|
7131 |
-
|
7132 |
-
|
7133 |
-
|
7134 |
-
|
7135 |
-
|
7136 |
-
distance = thisDistance;
|
7137 |
-
closestHandle = $( this );
|
7138 |
-
index = i;
|
7139 |
-
}
|
7140 |
-
});
|
7141 |
-
|
7142 |
-
// workaround for bug #3736 (if both handles of a range are at 0,
|
7143 |
-
// the first is always used as the one with least distance,
|
7144 |
-
// and moving it is obviously prevented by preventing negative ranges)
|
7145 |
-
if( o.range === true && this.values(1) === o.min ) {
|
7146 |
-
index += 1;
|
7147 |
-
closestHandle = $( this.handles[index] );
|
7148 |
-
}
|
7149 |
|
7150 |
-
|
7151 |
-
|
7152 |
-
|
7153 |
-
|
7154 |
-
|
7155 |
-
|
7156 |
-
|
7157 |
-
|
7158 |
-
|
7159 |
-
|
7160 |
-
.
|
7161 |
-
|
7162 |
-
|
7163 |
-
|
7164 |
-
|
7165 |
-
|
7166 |
-
|
7167 |
-
|
7168 |
-
|
7169 |
-
|
7170 |
-
|
7171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7172 |
|
7173 |
-
|
7174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
7175 |
}
|
7176 |
-
this._animateOff = true;
|
7177 |
-
return true;
|
7178 |
-
},
|
7179 |
-
|
7180 |
-
_mouseStart: function( event ) {
|
7181 |
-
return true;
|
7182 |
-
},
|
7183 |
-
|
7184 |
-
_mouseDrag: function( event ) {
|
7185 |
-
var position = { x: event.pageX, y: event.pageY },
|
7186 |
-
normValue = this._normValueFromMouse( position );
|
7187 |
-
|
7188 |
-
this._slide( event, this._handleIndex, normValue );
|
7189 |
|
7190 |
-
|
|
|
|
|
|
|
|
|
7191 |
},
|
7192 |
|
7193 |
-
|
7194 |
-
|
7195 |
-
this._mouseSliding = false;
|
7196 |
|
7197 |
-
|
7198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7199 |
|
7200 |
-
this.
|
7201 |
-
|
7202 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7203 |
|
7204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7205 |
},
|
7206 |
-
|
7207 |
-
|
7208 |
-
|
7209 |
},
|
7210 |
|
7211 |
-
|
7212 |
-
|
7213 |
-
|
7214 |
-
|
7215 |
-
|
7216 |
-
|
|
|
|
|
7217 |
|
7218 |
-
if ( this.
|
7219 |
-
|
7220 |
-
pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
|
7221 |
-
} else {
|
7222 |
-
pixelTotal = this.elementSize.height;
|
7223 |
-
pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
|
7224 |
}
|
|
|
7225 |
|
7226 |
-
|
7227 |
-
|
7228 |
-
|
7229 |
-
|
7230 |
-
|
7231 |
-
|
7232 |
-
|
7233 |
-
|
7234 |
-
|
7235 |
}
|
|
|
|
|
7236 |
|
7237 |
-
|
7238 |
-
|
|
|
7239 |
|
7240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7241 |
},
|
7242 |
|
7243 |
-
|
7244 |
-
|
7245 |
-
|
7246 |
-
|
7247 |
-
|
7248 |
-
|
7249 |
-
uiHash.value = this.values( index );
|
7250 |
-
uiHash.values = this.values();
|
7251 |
}
|
7252 |
-
|
7253 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7254 |
|
7255 |
-
|
7256 |
-
|
7257 |
-
|
7258 |
-
|
7259 |
|
7260 |
-
|
7261 |
-
|
|
|
7262 |
|
7263 |
-
if (
|
7264 |
-
|
7265 |
-
) {
|
7266 |
-
newVal = otherVal;
|
7267 |
}
|
7268 |
|
7269 |
-
if (
|
7270 |
-
|
7271 |
-
|
7272 |
-
|
7273 |
-
|
7274 |
-
handle: this.handles[ index ],
|
7275 |
-
value: newVal,
|
7276 |
-
values: newValues
|
7277 |
-
} );
|
7278 |
-
otherVal = this.values( index ? 0 : 1 );
|
7279 |
-
if ( allowed !== false ) {
|
7280 |
-
this.values( index, newVal, true );
|
7281 |
}
|
7282 |
}
|
7283 |
} else {
|
7284 |
-
|
7285 |
-
// A slide can be canceled by returning false from the slide callback
|
7286 |
-
allowed = this._trigger( "slide", event, {
|
7287 |
-
handle: this.handles[ index ],
|
7288 |
-
value: newVal
|
7289 |
-
} );
|
7290 |
-
if ( allowed !== false ) {
|
7291 |
-
this.value( newVal );
|
7292 |
-
}
|
7293 |
-
}
|
7294 |
-
}
|
7295 |
-
},
|
7296 |
-
|
7297 |
-
_stop: function( event, index ) {
|
7298 |
-
var uiHash = {
|
7299 |
-
handle: this.handles[ index ],
|
7300 |
-
value: this.value()
|
7301 |
-
};
|
7302 |
-
if ( this.options.values && this.options.values.length ) {
|
7303 |
-
uiHash.value = this.values( index );
|
7304 |
-
uiHash.values = this.values();
|
7305 |
}
|
|
|
|
|
|
|
7306 |
|
7307 |
-
|
|
|
|
|
|
|
7308 |
},
|
7309 |
|
7310 |
-
|
7311 |
-
|
7312 |
-
|
7313 |
-
handle: this.handles[ index ],
|
7314 |
-
value: this.value()
|
7315 |
-
};
|
7316 |
-
if ( this.options.values && this.options.values.length ) {
|
7317 |
-
uiHash.value = this.values( index );
|
7318 |
-
uiHash.values = this.values();
|
7319 |
-
}
|
7320 |
|
7321 |
-
|
7322 |
-
|
7323 |
},
|
7324 |
|
7325 |
-
|
7326 |
-
if (
|
7327 |
-
this.
|
7328 |
-
this._refreshValue();
|
7329 |
-
this._change( null, 0 );
|
7330 |
-
return;
|
7331 |
}
|
7332 |
|
7333 |
-
|
7334 |
},
|
7335 |
|
7336 |
-
|
7337 |
-
var
|
7338 |
-
newValues,
|
7339 |
-
i;
|
7340 |
-
|
7341 |
-
if ( arguments.length > 1 ) {
|
7342 |
-
this.options.values[ index ] = this._trimAlignValue( newValue );
|
7343 |
-
this._refreshValue();
|
7344 |
-
this._change( null, index );
|
7345 |
-
return;
|
7346 |
-
}
|
7347 |
|
7348 |
-
|
7349 |
-
|
7350 |
-
|
7351 |
-
|
7352 |
-
|
7353 |
-
|
7354 |
-
|
7355 |
-
|
7356 |
-
this.
|
7357 |
-
}
|
7358 |
-
|
7359 |
-
|
7360 |
-
|
7361 |
-
|
7362 |
-
|
7363 |
-
|
7364 |
-
|
7365 |
-
|
7366 |
-
}
|
7367 |
},
|
7368 |
|
7369 |
-
|
7370 |
-
|
7371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7372 |
|
7373 |
-
|
7374 |
-
valsLength = this.options.values.length;
|
7375 |
-
}
|
7376 |
|
7377 |
-
|
7378 |
|
7379 |
-
|
7380 |
-
case "disabled":
|
7381 |
-
if ( value ) {
|
7382 |
-
this.handles.filter( ".ui-state-focus" ).blur();
|
7383 |
-
this.handles.removeClass( "ui-state-hover" );
|
7384 |
-
this.handles.propAttr( "disabled", true );
|
7385 |
-
this.element.addClass( "ui-disabled" );
|
7386 |
-
} else {
|
7387 |
-
this.handles.propAttr( "disabled", false );
|
7388 |
-
this.element.removeClass( "ui-disabled" );
|
7389 |
-
}
|
7390 |
-
break;
|
7391 |
-
case "orientation":
|
7392 |
-
this._detectOrientation();
|
7393 |
-
this.element
|
7394 |
-
.removeClass( "ui-slider-horizontal ui-slider-vertical" )
|
7395 |
-
.addClass( "ui-slider-" + this.orientation );
|
7396 |
-
this._refreshValue();
|
7397 |
-
break;
|
7398 |
-
case "value":
|
7399 |
-
this._animateOff = true;
|
7400 |
-
this._refreshValue();
|
7401 |
-
this._change( null, 0 );
|
7402 |
-
this._animateOff = false;
|
7403 |
-
break;
|
7404 |
-
case "values":
|
7405 |
-
this._animateOff = true;
|
7406 |
-
this._refreshValue();
|
7407 |
-
for ( i = 0; i < valsLength; i += 1 ) {
|
7408 |
-
this._change( null, i );
|
7409 |
-
}
|
7410 |
-
this._animateOff = false;
|
7411 |
-
break;
|
7412 |
-
}
|
7413 |
-
},
|
7414 |
|
7415 |
-
|
7416 |
-
|
7417 |
-
|
7418 |
-
var val = this.options.value;
|
7419 |
-
val = this._trimAlignValue( val );
|
7420 |
|
7421 |
-
|
7422 |
-
|
|
|
|
|
7423 |
|
7424 |
-
|
7425 |
-
|
7426 |
-
|
7427 |
-
|
7428 |
-
|
7429 |
-
|
7430 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7431 |
|
7432 |
-
|
7433 |
-
|
7434 |
-
|
7435 |
|
7436 |
-
|
7437 |
-
|
7438 |
-
// .slice() creates a copy of the array
|
7439 |
-
// this copy gets trimmed by min and max and then returned
|
7440 |
-
vals = this.options.values.slice();
|
7441 |
-
for ( i = 0; i < vals.length; i+= 1) {
|
7442 |
-
vals[ i ] = this._trimAlignValue( vals[ i ] );
|
7443 |
-
}
|
7444 |
|
7445 |
-
|
7446 |
-
|
|
|
7447 |
},
|
7448 |
-
|
7449 |
-
// returns the step-aligned value that val is closest to, between (inclusive) min and max
|
7450 |
-
_trimAlignValue: function( val ) {
|
7451 |
-
if ( val <= this._valueMin() ) {
|
7452 |
-
return this._valueMin();
|
7453 |
-
}
|
7454 |
-
if ( val >= this._valueMax() ) {
|
7455 |
-
return this._valueMax();
|
7456 |
-
}
|
7457 |
-
var step = ( this.options.step > 0 ) ? this.options.step : 1,
|
7458 |
-
valModStep = (val - this._valueMin()) % step,
|
7459 |
-
alignValue = val - valModStep;
|
7460 |
|
7461 |
-
|
7462 |
-
|
7463 |
-
|
|
|
|
|
|
|
|
|
|
|
7464 |
|
7465 |
-
|
7466 |
-
|
7467 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7468 |
},
|
7469 |
|
7470 |
-
|
7471 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7472 |
},
|
7473 |
|
7474 |
-
|
7475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7476 |
},
|
7477 |
-
|
7478 |
-
_refreshValue: function() {
|
7479 |
-
var oRange = this.options.range,
|
7480 |
-
o = this.options,
|
7481 |
-
self = this,
|
7482 |
-
animate = ( !this._animateOff ) ? o.animate : false,
|
7483 |
-
valPercent,
|
7484 |
-
_set = {},
|
7485 |
-
lastValPercent,
|
7486 |
-
value,
|
7487 |
-
valueMin,
|
7488 |
-
valueMax;
|
7489 |
|
7490 |
-
|
7491 |
-
|
7492 |
-
|
7493 |
-
|
7494 |
-
|
7495 |
-
if ( self.options.range === true ) {
|
7496 |
-
if ( self.orientation === "horizontal" ) {
|
7497 |
-
if ( i === 0 ) {
|
7498 |
-
self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
|
7499 |
-
}
|
7500 |
-
if ( i === 1 ) {
|
7501 |
-
self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
|
7502 |
-
}
|
7503 |
-
} else {
|
7504 |
-
if ( i === 0 ) {
|
7505 |
-
self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
|
7506 |
-
}
|
7507 |
-
if ( i === 1 ) {
|
7508 |
-
self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
|
7509 |
-
}
|
7510 |
-
}
|
7511 |
-
}
|
7512 |
-
lastValPercent = valPercent;
|
7513 |
-
});
|
7514 |
-
} else {
|
7515 |
-
value = this.value();
|
7516 |
-
valueMin = this._valueMin();
|
7517 |
-
valueMax = this._valueMax();
|
7518 |
-
valPercent = ( valueMax !== valueMin ) ?
|
7519 |
-
( value - valueMin ) / ( valueMax - valueMin ) * 100 :
|
7520 |
-
0;
|
7521 |
-
_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
|
7522 |
-
this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
|
7523 |
|
7524 |
-
|
7525 |
-
|
7526 |
-
|
7527 |
-
|
7528 |
-
|
7529 |
-
|
7530 |
-
if ( oRange === "min" && this.orientation === "vertical" ) {
|
7531 |
-
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
|
7532 |
-
}
|
7533 |
-
if ( oRange === "max" && this.orientation === "vertical" ) {
|
7534 |
-
this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
|
7535 |
-
}
|
7536 |
}
|
7537 |
-
}
|
7538 |
-
|
7539 |
-
});
|
7540 |
-
|
7541 |
-
$.extend( $.ui.slider, {
|
7542 |
-
version: "1.8.17"
|
7543 |
-
});
|
7544 |
-
|
7545 |
-
}(jQuery));
|
7546 |
-
/*
|
7547 |
-
* jQuery UI Tabs 1.8.17
|
7548 |
-
*
|
7549 |
-
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
7550 |
-
* Dual licensed under the MIT or GPL Version 2 licenses.
|
7551 |
-
* http://jquery.org/license
|
7552 |
-
*
|
7553 |
-
* http://docs.jquery.com/UI/Tabs
|
7554 |
-
*
|
7555 |
-
* Depends:
|
7556 |
-
* jquery.ui.core.js
|
7557 |
-
* jquery.ui.widget.js
|
7558 |
-
*/
|
7559 |
-
(function( $, undefined ) {
|
7560 |
-
|
7561 |
-
var tabId = 0,
|
7562 |
-
listId = 0;
|
7563 |
|
7564 |
-
|
7565 |
-
return ++tabId;
|
7566 |
-
}
|
7567 |
|
7568 |
-
|
7569 |
-
|
7570 |
-
}
|
7571 |
|
7572 |
-
|
7573 |
-
|
7574 |
-
|
7575 |
-
|
7576 |
-
|
7577 |
-
|
7578 |
-
|
7579 |
-
|
7580 |
-
|
7581 |
-
|
7582 |
-
|
7583 |
-
|
7584 |
-
|
7585 |
-
|
7586 |
-
|
7587 |
-
|
7588 |
-
|
7589 |
-
|
7590 |
-
|
7591 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
7592 |
},
|
7593 |
|
7594 |
-
|
7595 |
-
|
7596 |
-
|
|
|
|
|
|
|
7597 |
|
7598 |
-
|
7599 |
-
|
7600 |
-
|
7601 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7602 |
}
|
7603 |
-
this.
|
7604 |
-
} else {
|
7605 |
-
this.options[ key ] = value;
|
7606 |
-
this._tabify();
|
7607 |
}
|
7608 |
},
|
7609 |
|
7610 |
-
|
7611 |
-
|
7612 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7613 |
},
|
7614 |
|
7615 |
-
|
7616 |
-
|
7617 |
-
|
7618 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7619 |
|
7620 |
-
|
7621 |
-
|
7622 |
-
|
7623 |
-
|
7624 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7625 |
|
7626 |
-
|
7627 |
-
|
7628 |
-
|
7629 |
-
|
7630 |
-
|
7631 |
-
|
7632 |
-
|
|
|
|
|
7633 |
|
7634 |
-
|
7635 |
-
|
7636 |
-
|
7637 |
-
|
7638 |
-
|
7639 |
-
|
7640 |
-
|
7641 |
-
|
7642 |
-
|
|
|
|
|
7643 |
},
|
7644 |
|
7645 |
-
|
7646 |
-
|
7647 |
-
|
7648 |
-
|
|
|
|
|
|
|
7649 |
|
7650 |
-
|
7651 |
-
|
7652 |
-
|
7653 |
-
return $( "a", this )[ 0 ];
|
7654 |
-
});
|
7655 |
-
this.panels = $( [] );
|
7656 |
-
|
7657 |
-
this.anchors.each(function( i, a ) {
|
7658 |
-
var href = $( a ).attr( "href" );
|
7659 |
-
// For dynamically created HTML that contains a hash as href IE < 8 expands
|
7660 |
-
// such href to the full page url with hash and then misinterprets tab as ajax.
|
7661 |
-
// Same consideration applies for an added tab with a fragment identifier
|
7662 |
-
// since a[href=#fragment-identifier] does unexpectedly not match.
|
7663 |
-
// Thus normalize href attribute...
|
7664 |
-
var hrefBase = href.split( "#" )[ 0 ],
|
7665 |
-
baseEl;
|
7666 |
-
if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
|
7667 |
-
( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
|
7668 |
-
href = a.hash;
|
7669 |
-
a.href = href;
|
7670 |
-
}
|
7671 |
|
7672 |
-
|
7673 |
-
|
7674 |
-
|
7675 |
-
|
7676 |
-
|
7677 |
-
|
7678 |
-
|
7679 |
-
|
7680 |
-
|
7681 |
-
|
7682 |
-
|
7683 |
-
|
7684 |
-
|
7685 |
-
|
7686 |
-
a.href = "#" + id;
|
7687 |
-
var $panel = self.element.find( "#" + id );
|
7688 |
-
if ( !$panel.length ) {
|
7689 |
-
$panel = $( o.panelTemplate )
|
7690 |
-
.attr( "id", id )
|
7691 |
-
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
|
7692 |
-
.insertAfter( self.panels[ i - 1 ] || self.list );
|
7693 |
-
$panel.data( "destroy.tabs", true );
|
7694 |
-
}
|
7695 |
-
self.panels = self.panels.add( $panel );
|
7696 |
-
// invalid tab href
|
7697 |
-
} else {
|
7698 |
-
o.disabled.push( i );
|
7699 |
-
}
|
7700 |
-
});
|
7701 |
|
7702 |
-
|
7703 |
-
|
7704 |
-
|
7705 |
-
|
7706 |
-
|
7707 |
-
|
7708 |
-
|
7709 |
-
|
7710 |
-
// Selected tab
|
7711 |
-
// use "selected" option or try to retrieve:
|
7712 |
-
// 1. from fragment identifier in url
|
7713 |
-
// 2. from cookie
|
7714 |
-
// 3. from selected class attribute on <li>
|
7715 |
-
if ( o.selected === undefined ) {
|
7716 |
-
if ( location.hash ) {
|
7717 |
-
this.anchors.each(function( i, a ) {
|
7718 |
-
if ( a.hash == location.hash ) {
|
7719 |
-
o.selected = i;
|
7720 |
-
return false;
|
7721 |
-
}
|
7722 |
-
});
|
7723 |
-
}
|
7724 |
-
if ( typeof o.selected !== "number" && o.cookie ) {
|
7725 |
-
o.selected = parseInt( self._cookie(), 10 );
|
7726 |
-
}
|
7727 |
-
if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
|
7728 |
-
o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
|
7729 |
-
}
|
7730 |
-
o.selected = o.selected || ( this.lis.length ? 0 : -1 );
|
7731 |
-
} else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
|
7732 |
-
o.selected = -1;
|
7733 |
-
}
|
7734 |
|
7735 |
-
|
7736 |
-
|
7737 |
-
|
7738 |
-
: 0;
|
7739 |
|
7740 |
-
|
7741 |
-
|
7742 |
-
|
7743 |
-
|
7744 |
-
|
7745 |
-
|
7746 |
-
|
7747 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7748 |
|
7749 |
-
|
7750 |
-
|
7751 |
-
|
|
|
|
|
|
|
|
|
7752 |
|
7753 |
-
|
7754 |
-
|
7755 |
-
|
7756 |
-
// check for length avoids error when initializing empty list
|
7757 |
-
if ( o.selected >= 0 && this.anchors.length ) {
|
7758 |
-
self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
|
7759 |
-
this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
|
7760 |
|
7761 |
-
|
7762 |
-
|
7763 |
-
|
7764 |
-
|
7765 |
-
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7766 |
|
7767 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7768 |
}
|
|
|
|
|
|
|
7769 |
|
7770 |
-
|
7771 |
-
|
7772 |
-
|
7773 |
-
|
7774 |
-
|
7775 |
-
|
7776 |
-
|
7777 |
-
|
7778 |
-
|
|
|
|
|
7779 |
}
|
|
|
7780 |
|
7781 |
-
|
7782 |
-
|
7783 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7784 |
|
7785 |
-
|
7786 |
-
|
7787 |
-
|
|
|
7788 |
}
|
7789 |
|
7790 |
-
|
7791 |
-
|
7792 |
-
|
7793 |
-
|
7794 |
-
!$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
|
7795 |
}
|
7796 |
|
7797 |
-
|
7798 |
-
|
7799 |
-
|
7800 |
-
|
7801 |
-
|
7802 |
-
// remove all handlers before, tabify may run on existing tabs after add or option change
|
7803 |
-
this.lis.add( this.anchors ).unbind( ".tabs" );
|
7804 |
|
7805 |
-
|
7806 |
-
|
7807 |
-
|
7808 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7809 |
}
|
7810 |
-
}
|
7811 |
-
|
7812 |
-
|
7813 |
-
|
7814 |
-
this.
|
7815 |
-
|
7816 |
-
});
|
7817 |
-
this.lis.bind( "mouseout.tabs", function() {
|
7818 |
-
removeState( "hover", $( this ) );
|
7819 |
-
});
|
7820 |
-
this.anchors.bind( "focus.tabs", function() {
|
7821 |
-
addState( "focus", $( this ).closest( "li" ) );
|
7822 |
-
});
|
7823 |
-
this.anchors.bind( "blur.tabs", function() {
|
7824 |
-
removeState( "focus", $( this ).closest( "li" ) );
|
7825 |
-
});
|
7826 |
}
|
|
|
7827 |
|
7828 |
-
|
7829 |
-
|
7830 |
-
|
7831 |
-
|
7832 |
-
|
7833 |
-
|
7834 |
-
|
7835 |
-
|
7836 |
-
|
|
|
|
|
|
|
7837 |
}
|
|
|
7838 |
|
7839 |
-
|
7840 |
-
|
7841 |
-
|
7842 |
-
|
7843 |
-
|
7844 |
-
|
7845 |
-
|
|
|
|
|
|
|
7846 |
}
|
|
|
7847 |
|
7848 |
-
|
7849 |
-
|
7850 |
-
|
7851 |
-
|
7852 |
-
|
7853 |
-
|
7854 |
-
|
7855 |
-
|
7856 |
-
|
7857 |
-
|
7858 |
-
|
7859 |
-
|
7860 |
-
$show.removeClass( "ui-tabs-hide" );
|
7861 |
-
self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
|
7862 |
-
};
|
7863 |
|
7864 |
-
|
7865 |
-
|
7866 |
-
|
7867 |
-
|
7868 |
-
|
7869 |
-
|
7870 |
-
resetStyle( $hide, hideFx );
|
7871 |
-
self.element.dequeue( "tabs" );
|
7872 |
-
});
|
7873 |
-
}
|
7874 |
-
: function( clicked, $hide, $show ) {
|
7875 |
-
self.lis.removeClass( "ui-tabs-selected ui-state-active" );
|
7876 |
-
$hide.addClass( "ui-tabs-hide" );
|
7877 |
-
self.element.dequeue( "tabs" );
|
7878 |
-
};
|
7879 |
|
7880 |
-
|
7881 |
-
|
7882 |
-
|
7883 |
-
|
7884 |
-
|
7885 |
-
|
7886 |
-
|
7887 |
-
|
7888 |
-
|
7889 |
-
|
7890 |
-
|
7891 |
-
if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
|
7892 |
-
$li.hasClass( "ui-state-disabled" ) ||
|
7893 |
-
$li.hasClass( "ui-state-processing" ) ||
|
7894 |
-
self.panels.filter( ":animated" ).length ||
|
7895 |
-
self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
|
7896 |
-
this.blur();
|
7897 |
-
return false;
|
7898 |
-
}
|
7899 |
|
7900 |
-
|
|
|
|
|
7901 |
|
7902 |
-
|
|
|
|
|
|
|
|
|
7903 |
|
7904 |
-
|
7905 |
-
|
7906 |
-
|
7907 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7908 |
|
7909 |
-
|
7910 |
-
|
7911 |
-
|
|
|
|
|
7912 |
|
7913 |
-
|
7914 |
-
|
7915 |
-
|
|
|
7916 |
|
7917 |
-
|
7918 |
-
|
7919 |
-
|
7920 |
-
|
7921 |
-
|
7922 |
-
|
7923 |
|
7924 |
-
|
7925 |
-
|
7926 |
-
|
|
|
7927 |
|
7928 |
-
|
7929 |
-
|
|
|
|
|
|
|
7930 |
|
7931 |
-
|
7932 |
-
|
|
|
|
|
7933 |
}
|
7934 |
}
|
7935 |
-
|
7936 |
-
if ( o.cookie ) {
|
7937 |
-
self._cookie( o.selected, o.cookie );
|
7938 |
}
|
|
|
|
|
|
|
7939 |
|
7940 |
-
|
7941 |
-
|
7942 |
-
|
7943 |
-
|
7944 |
-
|
7945 |
-
|
7946 |
-
|
7947 |
-
|
7948 |
-
|
7949 |
-
|
7950 |
-
|
7951 |
-
self.load( self.anchors.index( this ) );
|
7952 |
-
} else {
|
7953 |
-
throw "jQuery UI Tabs: Mismatching fragment identifier.";
|
7954 |
-
}
|
7955 |
|
7956 |
-
|
7957 |
-
|
7958 |
-
|
7959 |
-
// which can become a usability and annoying problem with tabs('rotate').
|
7960 |
-
if ( $.browser.msie ) {
|
7961 |
-
this.blur();
|
7962 |
-
}
|
7963 |
-
});
|
7964 |
|
7965 |
-
|
7966 |
-
|
7967 |
-
return false;
|
7968 |
-
});
|
7969 |
-
},
|
7970 |
|
7971 |
-
|
7972 |
-
|
7973 |
-
|
7974 |
-
|
7975 |
-
|
|
|
7976 |
}
|
7977 |
|
7978 |
-
|
7979 |
-
|
|
|
|
|
|
|
|
|
7980 |
|
7981 |
-
|
7982 |
-
|
|
|
7983 |
|
7984 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
7985 |
|
7986 |
-
|
7987 |
-
|
7988 |
-
.
|
7989 |
-
|
|
|
7990 |
|
7991 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7992 |
|
7993 |
-
|
7994 |
-
|
7995 |
-
|
7996 |
-
|
7997 |
-
|
7998 |
-
var $this = $( this ).unbind( ".tabs" );
|
7999 |
-
$.each( [ "href", "load", "cache" ], function( i, prefix ) {
|
8000 |
-
$this.removeData( prefix + ".tabs" );
|
8001 |
-
});
|
8002 |
-
});
|
8003 |
|
8004 |
-
|
8005 |
-
|
8006 |
-
$( this ).remove();
|
8007 |
} else {
|
8008 |
-
|
8009 |
-
"ui-state-default",
|
8010 |
-
"ui-corner-top",
|
8011 |
-
"ui-tabs-selected",
|
8012 |
-
"ui-state-active",
|
8013 |
-
"ui-state-hover",
|
8014 |
-
"ui-state-focus",
|
8015 |
-
"ui-state-disabled",
|
8016 |
-
"ui-tabs-panel",
|
8017 |
-
"ui-widget-content",
|
8018 |
-
"ui-corner-bottom",
|
8019 |
-
"ui-tabs-hide"
|
8020 |
-
].join( " " ) );
|
8021 |
}
|
8022 |
-
});
|
8023 |
|
8024 |
-
|
8025 |
-
|
|
|
|
|
8026 |
}
|
8027 |
-
|
8028 |
-
return this;
|
8029 |
},
|
8030 |
|
8031 |
-
|
8032 |
-
|
8033 |
-
|
8034 |
-
|
8035 |
-
|
8036 |
-
|
8037 |
-
|
8038 |
-
|
8039 |
-
|
8040 |
-
|
8041 |
-
|
8042 |
-
|
8043 |
-
|
8044 |
-
|
8045 |
-
if (
|
8046 |
-
|
8047 |
-
|
8048 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8049 |
}
|
8050 |
-
$panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
|
8051 |
|
8052 |
-
|
8053 |
-
|
8054 |
-
|
8055 |
-
|
8056 |
-
|
8057 |
-
|
|
|
|
|
|
|
|
|
8058 |
}
|
|
|
8059 |
|
8060 |
-
|
8061 |
-
|
8062 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8063 |
|
8064 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8065 |
|
8066 |
-
|
8067 |
-
|
8068 |
-
|
8069 |
-
$panel.removeClass( "ui-tabs-hide" );
|
8070 |
-
this.element.queue( "tabs", function() {
|
8071 |
-
self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
|
8072 |
-
});
|
8073 |
|
8074 |
-
|
8075 |
-
|
|
|
|
|
|
|
8076 |
|
8077 |
-
|
8078 |
-
return this;
|
8079 |
},
|
8080 |
|
8081 |
-
|
8082 |
-
|
8083 |
-
var
|
8084 |
-
|
8085 |
-
|
8086 |
|
8087 |
-
|
8088 |
-
|
8089 |
-
if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
|
8090 |
-
this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
|
8091 |
}
|
8092 |
|
8093 |
-
|
8094 |
-
|
8095 |
-
return n != index;
|
8096 |
-
}),
|
8097 |
-
function( n, i ) {
|
8098 |
-
return n >= index ? --n : n;
|
8099 |
-
});
|
8100 |
-
|
8101 |
-
this._tabify();
|
8102 |
-
|
8103 |
-
this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
|
8104 |
-
return this;
|
8105 |
},
|
8106 |
|
8107 |
-
|
8108 |
-
|
8109 |
-
|
8110 |
-
|
|
|
|
|
|
|
|
|
8111 |
return;
|
8112 |
}
|
8113 |
|
8114 |
-
this.
|
8115 |
-
|
8116 |
-
|
8117 |
-
|
8118 |
-
|
8119 |
-
|
8120 |
-
return this;
|
8121 |
-
},
|
8122 |
|
8123 |
-
|
8124 |
-
|
8125 |
-
|
8126 |
-
|
8127 |
-
|
8128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
8129 |
|
8130 |
-
|
8131 |
-
|
|
|
|
|
8132 |
|
8133 |
-
this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8134 |
}
|
|
|
8135 |
|
8136 |
-
|
|
|
|
|
8137 |
},
|
8138 |
|
8139 |
-
|
8140 |
-
|
8141 |
-
if (
|
8142 |
-
|
8143 |
-
index = this.options.selected;
|
8144 |
-
} else {
|
8145 |
-
return this;
|
8146 |
-
}
|
8147 |
}
|
8148 |
-
this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
|
8149 |
-
return this;
|
8150 |
-
},
|
8151 |
|
8152 |
-
|
8153 |
-
|
8154 |
-
|
8155 |
-
|
8156 |
-
|
8157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
8158 |
|
8159 |
-
|
|
|
|
|
|
|
8160 |
|
8161 |
-
|
8162 |
-
if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
|
8163 |
-
this.element.dequeue( "tabs" );
|
8164 |
return;
|
8165 |
}
|
|
|
|
|
|
|
|
|
|
|
8166 |
|
8167 |
-
|
8168 |
-
|
|
|
|
|
|
|
8169 |
|
8170 |
-
if (
|
8171 |
-
|
8172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
8173 |
}
|
|
|
|
|
|
|
8174 |
|
8175 |
-
|
8176 |
-
|
8177 |
-
|
8178 |
-
|
8179 |
|
8180 |
-
|
8181 |
-
|
|
|
8182 |
|
8183 |
-
|
8184 |
-
|
8185 |
-
|
8186 |
|
8187 |
-
|
8188 |
-
|
8189 |
-
|
8190 |
-
|
8191 |
-
catch ( e ) {}
|
8192 |
-
},
|
8193 |
-
error: function( xhr, s, e ) {
|
8194 |
-
// take care of tab labels
|
8195 |
-
self._cleanup();
|
8196 |
|
8197 |
-
|
8198 |
-
|
8199 |
-
|
8200 |
-
// called after the user has selected another tab.
|
8201 |
-
// Pass the anchor that initiated this request allows
|
8202 |
-
// loadError to manipulate the tab content panel via $(a.hash)
|
8203 |
-
o.ajaxOptions.error( xhr, s, index, a );
|
8204 |
-
}
|
8205 |
-
catch ( e ) {}
|
8206 |
-
}
|
8207 |
-
} ) );
|
8208 |
|
8209 |
-
|
8210 |
-
|
|
|
|
|
|
|
|
|
|
|
8211 |
|
8212 |
-
|
|
|
|
|
|
|
8213 |
},
|
8214 |
|
8215 |
-
|
8216 |
-
|
8217 |
-
|
8218 |
-
|
|
|
8219 |
|
8220 |
-
|
8221 |
-
|
8222 |
-
|
|
|
|
|
8223 |
|
8224 |
-
|
8225 |
-
if (
|
8226 |
-
|
8227 |
-
|
|
|
8228 |
}
|
8229 |
|
8230 |
-
|
8231 |
-
|
8232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8233 |
},
|
8234 |
|
8235 |
-
|
8236 |
-
|
8237 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8238 |
},
|
8239 |
|
8240 |
-
|
8241 |
-
|
8242 |
-
|
8243 |
-
|
|
|
|
|
|
|
|
|
8244 |
|
8245 |
-
|
8246 |
-
|
8247 |
-
|
|
|
|
|
|
|
|
|
8248 |
|
8249 |
-
|
8250 |
-
|
8251 |
-
*/
|
8252 |
|
8253 |
-
|
8254 |
-
|
8255 |
-
|
8256 |
-
|
8257 |
-
|
8258 |
-
rotate: function( ms, continuing ) {
|
8259 |
-
var self = this,
|
8260 |
-
o = this.options;
|
8261 |
|
8262 |
-
|
8263 |
-
|
8264 |
-
|
8265 |
-
|
8266 |
-
|
8267 |
-
|
8268 |
-
|
8269 |
-
|
8270 |
-
|
8271 |
-
|
8272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8273 |
|
8274 |
-
|
8275 |
-
|
8276 |
-
if (
|
8277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8278 |
}
|
8279 |
}
|
8280 |
-
|
8281 |
-
t = o.selected;
|
8282 |
-
rotate();
|
8283 |
-
});
|
8284 |
|
8285 |
-
|
8286 |
-
|
8287 |
-
|
8288 |
-
|
8289 |
-
|
8290 |
-
// stop rotation
|
8291 |
-
} else {
|
8292 |
-
clearTimeout( self.rotation );
|
8293 |
-
this.element.unbind( "tabsshow", rotate );
|
8294 |
-
this.anchors.unbind( o.event + ".tabs", stop );
|
8295 |
-
delete this._rotate;
|
8296 |
-
delete this._unrotate;
|
8297 |
}
|
8298 |
|
8299 |
-
|
8300 |
-
|
8301 |
-
})
|
|
|
|
|
|
|
8302 |
|
8303 |
-
|
8304 |
-
|
8305 |
-
|
8306 |
-
|
8307 |
-
|
8308 |
-
|
8309 |
-
|
8310 |
-
|
8311 |
-
|
8312 |
-
|
8313 |
-
|
8314 |
-
|
8315 |
-
*/
|
8316 |
-
(function( $, undefined ) {
|
8317 |
|
8318 |
-
|
|
|
|
|
|
|
|
|
|
|
8319 |
|
8320 |
-
|
8321 |
-
|
8322 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8323 |
|
8324 |
-
|
8325 |
-
|
8326 |
-
Settings for (groups of) date pickers are maintained in an instance object,
|
8327 |
-
allowing multiple different settings on the same page. */
|
8328 |
|
8329 |
-
|
8330 |
-
|
8331 |
-
|
8332 |
-
|
8333 |
-
|
8334 |
-
|
8335 |
-
|
8336 |
-
|
8337 |
-
|
8338 |
-
|
8339 |
-
|
8340 |
-
|
8341 |
-
|
8342 |
-
|
8343 |
-
|
8344 |
-
|
8345 |
-
|
8346 |
-
|
8347 |
-
|
8348 |
-
|
8349 |
-
|
8350 |
-
|
8351 |
-
|
8352 |
-
|
8353 |
-
|
8354 |
-
|
8355 |
-
|
8356 |
-
|
8357 |
-
|
8358 |
-
|
8359 |
-
|
8360 |
-
|
8361 |
-
|
8362 |
-
|
8363 |
-
|
8364 |
-
|
8365 |
-
|
8366 |
-
|
8367 |
-
|
8368 |
-
|
8369 |
-
|
8370 |
-
|
8371 |
-
|
8372 |
-
|
8373 |
-
|
8374 |
-
|
8375 |
-
|
8376 |
-
|
8377 |
-
|
8378 |
-
|
8379 |
-
|
8380 |
-
|
8381 |
-
|
8382 |
-
|
8383 |
-
|
8384 |
-
|
8385 |
-
|
8386 |
-
|
8387 |
-
|
8388 |
-
|
8389 |
-
|
8390 |
-
|
8391 |
-
// string value starting with '+' for current year + value
|
8392 |
-
minDate: null, // The earliest selectable date, or null for no limit
|
8393 |
-
maxDate: null, // The latest selectable date, or null for no limit
|
8394 |
-
duration: 'fast', // Duration of display/closure
|
8395 |
-
beforeShowDay: null, // Function that takes a date and returns an array with
|
8396 |
-
// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
|
8397 |
-
// [2] = cell title (optional), e.g. $.datepicker.noWeekends
|
8398 |
-
beforeShow: null, // Function that takes an input field and
|
8399 |
-
// returns a set of custom settings for the date picker
|
8400 |
-
onSelect: null, // Define a callback function when a date is selected
|
8401 |
-
onChangeMonthYear: null, // Define a callback function when the month or year is changed
|
8402 |
-
onClose: null, // Define a callback function when the datepicker is closed
|
8403 |
-
numberOfMonths: 1, // Number of months to show at a time
|
8404 |
-
showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
|
8405 |
-
stepMonths: 1, // Number of months to step back/forward
|
8406 |
-
stepBigMonths: 12, // Number of months to step back/forward for the big links
|
8407 |
-
altField: '', // Selector for an alternate field to store selected dates into
|
8408 |
-
altFormat: '', // The date format to use for the alternate field
|
8409 |
-
constrainInput: true, // The input is constrained by the current date format
|
8410 |
-
showButtonPanel: false, // True to show button panel, false to not show it
|
8411 |
-
autoSize: false, // True to size the input for the date format, false to leave as is
|
8412 |
-
disabled: false // The initial disabled state
|
8413 |
-
};
|
8414 |
-
$.extend(this._defaults, this.regional['']);
|
8415 |
-
this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
|
8416 |
-
}
|
8417 |
-
|
8418 |
-
$.extend(Datepicker.prototype, {
|
8419 |
-
/* Class name added to elements to indicate already configured with a date picker. */
|
8420 |
-
markerClassName: 'hasDatepicker',
|
8421 |
-
|
8422 |
-
//Keep track of the maximum number of rows displayed (see #7043)
|
8423 |
-
maxRows: 4,
|
8424 |
|
8425 |
-
|
8426 |
-
|
8427 |
-
|
8428 |
-
|
8429 |
-
|
8430 |
-
|
8431 |
-
|
8432 |
-
|
8433 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8434 |
},
|
8435 |
|
8436 |
-
/*
|
8437 |
-
|
8438 |
-
|
8439 |
-
|
8440 |
-
|
8441 |
-
|
8442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
8443 |
|
8444 |
-
|
8445 |
-
|
8446 |
-
|
8447 |
-
|
8448 |
-
|
8449 |
-
|
8450 |
-
|
8451 |
-
|
8452 |
-
|
8453 |
-
|
8454 |
-
|
8455 |
-
|
8456 |
-
|
8457 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8458 |
}
|
8459 |
}
|
8460 |
}
|
8461 |
-
|
8462 |
-
var inline = (nodeName == 'div' || nodeName == 'span');
|
8463 |
-
if (!target.id) {
|
8464 |
-
this.uuid += 1;
|
8465 |
-
target.id = 'dp' + this.uuid;
|
8466 |
-
}
|
8467 |
-
var inst = this._newInst($(target), inline);
|
8468 |
-
inst.settings = $.extend({}, settings || {}, inlineSettings || {});
|
8469 |
-
if (nodeName == 'input') {
|
8470 |
-
this._connectDatepicker(target, inst);
|
8471 |
-
} else if (inline) {
|
8472 |
-
this._inlineDatepicker(target, inst);
|
8473 |
-
}
|
8474 |
},
|
8475 |
|
8476 |
-
/*
|
8477 |
-
|
8478 |
-
|
8479 |
-
|
8480 |
-
selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
|
8481 |
-
drawMonth: 0, drawYear: 0, // month being drawn
|
8482 |
-
inline: inline, // is datepicker inline or not
|
8483 |
-
dpDiv: (!inline ? this.dpDiv : // presentation div
|
8484 |
-
bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
|
8485 |
},
|
8486 |
|
8487 |
-
/*
|
8488 |
-
|
8489 |
-
|
8490 |
-
inst.append = $([]);
|
8491 |
-
inst.trigger = $([]);
|
8492 |
-
if (input.hasClass(this.markerClassName))
|
8493 |
return;
|
8494 |
-
this._attachments(input, inst);
|
8495 |
-
input.addClass(this.markerClassName).keydown(this._doKeyDown).
|
8496 |
-
keypress(this._doKeyPress).keyup(this._doKeyUp).
|
8497 |
-
bind("setData.datepicker", function(event, key, value) {
|
8498 |
-
inst.settings[key] = value;
|
8499 |
-
}).bind("getData.datepicker", function(event, key) {
|
8500 |
-
return this._get(inst, key);
|
8501 |
-
});
|
8502 |
-
this._autoSize(inst);
|
8503 |
-
$.data(target, PROP_NAME, inst);
|
8504 |
-
//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
|
8505 |
-
if( inst.settings.disabled ) {
|
8506 |
-
this._disableDatepicker( target );
|
8507 |
}
|
8508 |
-
},
|
8509 |
|
8510 |
-
/* Make attachments based on settings. */
|
8511 |
-
_attachments: function(input, inst) {
|
8512 |
-
var appendText = this._get(inst, 'appendText');
|
8513 |
-
var isRTL = this._get(inst, 'isRTL');
|
8514 |
-
if (inst.append)
|
8515 |
-
inst.append.remove();
|
8516 |
-
if (appendText) {
|
8517 |
-
inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
|
8518 |
-
input[isRTL ? 'before' : 'after'](inst.append);
|
8519 |
-
}
|
8520 |
-
input.unbind('focus', this._showDatepicker);
|
8521 |
-
if (inst.trigger)
|
8522 |
-
inst.trigger.remove();
|
8523 |
-
var showOn = this._get(inst, 'showOn');
|
8524 |
-
if (showOn == 'focus' || showOn == 'both') // pop-
|
1 |
+
/*! jQuery UI - v1.10.2 - 2013-03-14
|
2 |
+
* http://jqueryui.com
|
3 |
+
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
|
4 |
+
* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
|
5 |
+
(function( $, undefined ) {
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
+
var uuid = 0,
|
8 |
+
runiqueId = /^ui-id-\d+$/;
|
9 |
+
|
10 |
+
// $.ui might exist from components with no dependencies, e.g., $.ui.position
|
11 |
$.ui = $.ui || {};
|
|
|
|
|
|
|
12 |
|
13 |
$.extend( $.ui, {
|
14 |
+
version: "1.10.2",
|
15 |
|
16 |
keyCode: {
|
|
|
17 |
BACKSPACE: 8,
|
|
|
18 |
COMMA: 188,
|
|
|
|
|
|
|
|
|
19 |
DELETE: 46,
|
20 |
DOWN: 40,
|
21 |
END: 35,
|
22 |
ENTER: 13,
|
23 |
ESCAPE: 27,
|
24 |
HOME: 36,
|
|
|
25 |
LEFT: 37,
|
|
|
26 |
NUMPAD_ADD: 107,
|
27 |
NUMPAD_DECIMAL: 110,
|
28 |
NUMPAD_DIVIDE: 111,
|
33 |
PAGE_UP: 33,
|
34 |
PERIOD: 190,
|
35 |
RIGHT: 39,
|
|
|
36 |
SPACE: 32,
|
37 |
TAB: 9,
|
38 |
+
UP: 38
|
|
|
39 |
}
|
40 |
});
|
41 |
|
42 |
// plugins
|
43 |
$.fn.extend({
|
44 |
+
focus: (function( orig ) {
|
45 |
+
return function( delay, fn ) {
|
46 |
+
return typeof delay === "number" ?
|
47 |
+
this.each(function() {
|
48 |
+
var elem = this;
|
49 |
+
setTimeout(function() {
|
50 |
+
$( elem ).focus();
|
51 |
+
if ( fn ) {
|
52 |
+
fn.call( elem );
|
53 |
+
}
|
54 |
+
}, delay );
|
55 |
+
}) :
|
56 |
+
orig.apply( this, arguments );
|
57 |
+
};
|
58 |
+
})( $.fn.focus ),
|
|
|
59 |
|
60 |
scrollParent: function() {
|
61 |
var scrollParent;
|
62 |
+
if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
|
63 |
scrollParent = this.parents().filter(function() {
|
64 |
+
return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
|
65 |
}).eq(0);
|
66 |
} else {
|
67 |
scrollParent = this.parents().filter(function() {
|
68 |
+
return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
|
69 |
}).eq(0);
|
70 |
}
|
71 |
|
72 |
+
return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
|
73 |
},
|
74 |
|
75 |
zIndex: function( zIndex ) {
|
101 |
return 0;
|
102 |
},
|
103 |
|
104 |
+
uniqueId: function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
return this.each(function() {
|
106 |
+
if ( !this.id ) {
|
107 |
+
this.id = "ui-id-" + (++uuid);
|
108 |
+
}
|
109 |
});
|
110 |
+
},
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
+
removeUniqueId: function() {
|
113 |
return this.each(function() {
|
114 |
+
if ( runiqueId.test( this.id ) ) {
|
115 |
+
$( this ).removeAttr( "id" );
|
116 |
+
}
|
117 |
});
|
118 |
+
}
|
119 |
});
|
120 |
|
121 |
// selectors
|
122 |
function focusable( element, isTabIndexNotNaN ) {
|
123 |
+
var map, mapName, img,
|
124 |
+
nodeName = element.nodeName.toLowerCase();
|
125 |
if ( "area" === nodeName ) {
|
126 |
+
map = element.parentNode;
|
127 |
+
mapName = map.name;
|
|
|
128 |
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
|
129 |
return false;
|
130 |
}
|
131 |
img = $( "img[usemap=#" + mapName + "]" )[0];
|
132 |
return !!img && visible( img );
|
133 |
}
|
134 |
+
return ( /input|select|textarea|button|object/.test( nodeName ) ?
|
135 |
+
!element.disabled :
|
136 |
+
"a" === nodeName ?
|
137 |
+
element.href || isTabIndexNotNaN :
|
138 |
+
isTabIndexNotNaN) &&
|
139 |
// the element and all of its ancestors must be visible
|
140 |
+
visible( element );
|
141 |
}
|
142 |
|
143 |
function visible( element ) {
|
144 |
+
return $.expr.filters.visible( element ) &&
|
145 |
+
!$( element ).parents().addBack().filter(function() {
|
146 |
+
return $.css( this, "visibility" ) === "hidden";
|
147 |
+
}).length;
|
148 |
}
|
149 |
|
150 |
$.extend( $.expr[ ":" ], {
|
151 |
+
data: $.expr.createPseudo ?
|
152 |
+
$.expr.createPseudo(function( dataName ) {
|
153 |
+
return function( elem ) {
|
154 |
+
return !!$.data( elem, dataName );
|
155 |
+
};
|
156 |
+
}) :
|
157 |
+
// support: jQuery <1.8
|
158 |
+
function( elem, i, match ) {
|
159 |
+
return !!$.data( elem, match[ 3 ] );
|
160 |
+
},
|
161 |
|
162 |
focusable: function( element ) {
|
163 |
return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
|
170 |
}
|
171 |
});
|
172 |
|
173 |
+
// support: jQuery <1.8
|
174 |
+
if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
|
175 |
+
$.each( [ "Width", "Height" ], function( i, name ) {
|
176 |
+
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
|
177 |
+
type = name.toLowerCase(),
|
178 |
+
orig = {
|
179 |
+
innerWidth: $.fn.innerWidth,
|
180 |
+
innerHeight: $.fn.innerHeight,
|
181 |
+
outerWidth: $.fn.outerWidth,
|
182 |
+
outerHeight: $.fn.outerHeight
|
183 |
+
};
|
184 |
+
|
185 |
+
function reduce( elem, size, border, margin ) {
|
186 |
+
$.each( side, function() {
|
187 |
+
size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
|
188 |
+
if ( border ) {
|
189 |
+
size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
|
190 |
+
}
|
191 |
+
if ( margin ) {
|
192 |
+
size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
|
193 |
+
}
|
194 |
+
});
|
195 |
+
return size;
|
196 |
+
}
|
197 |
+
|
198 |
+
$.fn[ "inner" + name ] = function( size ) {
|
199 |
+
if ( size === undefined ) {
|
200 |
+
return orig[ "inner" + name ].call( this );
|
201 |
+
}
|
202 |
|
203 |
+
return this.each(function() {
|
204 |
+
$( this ).css( type, reduce( this, size ) + "px" );
|
205 |
+
});
|
206 |
+
};
|
207 |
+
|
208 |
+
$.fn[ "outer" + name] = function( size, margin ) {
|
209 |
+
if ( typeof size !== "number" ) {
|
210 |
+
return orig[ "outer" + name ].call( this, size );
|
211 |
+
}
|
212 |
+
|
213 |
+
return this.each(function() {
|
214 |
+
$( this).css( type, reduce( this, size, true, margin ) + "px" );
|
215 |
+
});
|
216 |
+
};
|
217 |
});
|
218 |
+
}
|
219 |
|
220 |
+
// support: jQuery <1.8
|
221 |
+
if ( !$.fn.addBack ) {
|
222 |
+
$.fn.addBack = function( selector ) {
|
223 |
+
return this.add( selector == null ?
|
224 |
+
this.prevObject : this.prevObject.filter( selector )
|
225 |
+
);
|
226 |
+
};
|
227 |
+
}
|
228 |
|
229 |
+
// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
|
230 |
+
if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
|
231 |
+
$.fn.removeData = (function( removeData ) {
|
232 |
+
return function( key ) {
|
233 |
+
if ( arguments.length ) {
|
234 |
+
return removeData.call( this, $.camelCase( key ) );
|
235 |
+
} else {
|
236 |
+
return removeData.call( this );
|
237 |
+
}
|
238 |
+
};
|
239 |
+
})( $.fn.removeData );
|
240 |
+
}
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
// deprecated
|
247 |
+
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
|
248 |
+
|
249 |
+
$.support.selectstart = "onselectstart" in document.createElement( "div" );
|
250 |
+
$.fn.extend({
|
251 |
+
disableSelection: function() {
|
252 |
+
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
|
253 |
+
".ui-disableSelection", function( event ) {
|
254 |
+
event.preventDefault();
|
255 |
+
});
|
256 |
+
},
|
257 |
+
|
258 |
+
enableSelection: function() {
|
259 |
+
return this.unbind( ".ui-disableSelection" );
|
260 |
+
}
|
261 |
+
});
|
262 |
+
|
263 |
$.extend( $.ui, {
|
264 |
// $.ui.plugin is deprecated. Use the proxy pattern instead.
|
265 |
plugin: {
|
266 |
add: function( module, option, set ) {
|
267 |
+
var i,
|
268 |
+
proto = $.ui[ module ].prototype;
|
269 |
+
for ( i in set ) {
|
270 |
proto.plugins[ i ] = proto.plugins[ i ] || [];
|
271 |
proto.plugins[ i ].push( [ option, set[ i ] ] );
|
272 |
}
|
273 |
},
|
274 |
call: function( instance, name, args ) {
|
275 |
+
var i,
|
276 |
+
set = instance.plugins[ name ];
|
277 |
+
if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
|
278 |
return;
|
279 |
}
|
280 |
+
|
281 |
+
for ( i = 0; i < set.length; i++ ) {
|
282 |
if ( instance.options[ set[ i ][ 0 ] ] ) {
|
283 |
set[ i ][ 1 ].apply( instance.element, args );
|
284 |
}
|
285 |
}
|
286 |
}
|
287 |
},
|
288 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
// only used by resizable
|
290 |
hasScroll: function( el, a ) {
|
291 |
+
|
292 |
//If overflow is hidden, the element might have extra content, but the user wants to hide it
|
293 |
if ( $( el ).css( "overflow" ) === "hidden") {
|
294 |
return false;
|
295 |
}
|
296 |
+
|
297 |
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
|
298 |
has = false;
|
299 |
+
|
300 |
if ( el[ scroll ] > 0 ) {
|
301 |
return true;
|
302 |
}
|
303 |
+
|
304 |
// TODO: determine which cases actually cause this to happen
|
305 |
// if the element doesn't have the scroll set, see if it's possible to
|
306 |
// set the scroll
|
308 |
has = ( el[ scroll ] > 0 );
|
309 |
el[ scroll ] = 0;
|
310 |
return has;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
}
|
312 |
});
|
313 |
|
314 |
})( jQuery );
|
315 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
316 |
(function( $, undefined ) {
|
317 |
|
318 |
+
var uuid = 0,
|
319 |
+
slice = Array.prototype.slice,
|
320 |
+
_cleanData = $.cleanData;
|
321 |
+
$.cleanData = function( elems ) {
|
322 |
+
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
|
323 |
+
try {
|
324 |
+
$( elem ).triggerHandler( "remove" );
|
325 |
+
// http://bugs.jquery.com/ticket/8235
|
326 |
+
} catch( e ) {}
|
327 |
+
}
|
328 |
+
_cleanData( elems );
|
329 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
|
331 |
$.widget = function( name, base, prototype ) {
|
332 |
+
var fullName, existingConstructor, constructor, basePrototype,
|
333 |
+
// proxiedPrototype allows the provided prototype to remain unmodified
|
334 |
+
// so that it can be used as a mixin for multiple widgets (#8876)
|
335 |
+
proxiedPrototype = {},
|
336 |
+
namespace = name.split( "." )[ 0 ];
|
337 |
+
|
338 |
name = name.split( "." )[ 1 ];
|
339 |
fullName = namespace + "-" + name;
|
340 |
|
344 |
}
|
345 |
|
346 |
// create selector for plugin
|
347 |
+
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
|
348 |
+
return !!$.data( elem, fullName );
|
349 |
};
|
350 |
|
351 |
$[ namespace ] = $[ namespace ] || {};
|
352 |
+
existingConstructor = $[ namespace ][ name ];
|
353 |
+
constructor = $[ namespace ][ name ] = function( options, element ) {
|
354 |
+
// allow instantiation without "new" keyword
|
355 |
+
if ( !this._createWidget ) {
|
356 |
+
return new constructor( options, element );
|
357 |
+
}
|
358 |
+
|
359 |
// allow instantiation without initializing for simple inheritance
|
360 |
+
// must use "new" keyword (the code above always passes args)
|
361 |
if ( arguments.length ) {
|
362 |
this._createWidget( options, element );
|
363 |
}
|
364 |
};
|
365 |
+
// extend with the existing constructor to carry over any static properties
|
366 |
+
$.extend( constructor, existingConstructor, {
|
367 |
+
version: prototype.version,
|
368 |
+
// copy the object used to create the prototype in case we need to
|
369 |
+
// redefine the widget later
|
370 |
+
_proto: $.extend( {}, prototype ),
|
371 |
+
// track widgets that inherit from this widget in case this widget is
|
372 |
+
// redefined after a widget inherits from it
|
373 |
+
_childConstructors: []
|
374 |
+
});
|
375 |
|
376 |
+
basePrototype = new base();
|
377 |
// we need to make the options hash a property directly on the new instance
|
378 |
// otherwise we'll modify the options hash on the prototype that we're
|
379 |
// inheriting from
|
380 |
+
basePrototype.options = $.widget.extend( {}, basePrototype.options );
|
381 |
+
$.each( prototype, function( prop, value ) {
|
382 |
+
if ( !$.isFunction( value ) ) {
|
383 |
+
proxiedPrototype[ prop ] = value;
|
384 |
+
return;
|
385 |
+
}
|
386 |
+
proxiedPrototype[ prop ] = (function() {
|
387 |
+
var _super = function() {
|
388 |
+
return base.prototype[ prop ].apply( this, arguments );
|
389 |
+
},
|
390 |
+
_superApply = function( args ) {
|
391 |
+
return base.prototype[ prop ].apply( this, args );
|
392 |
+
};
|
393 |
+
return function() {
|
394 |
+
var __super = this._super,
|
395 |
+
__superApply = this._superApply,
|
396 |
+
returnValue;
|
397 |
+
|
398 |
+
this._super = _super;
|
399 |
+
this._superApply = _superApply;
|
400 |
+
|
401 |
+
returnValue = value.apply( this, arguments );
|
402 |
+
|
403 |
+
this._super = __super;
|
404 |
+
this._superApply = __superApply;
|
405 |
+
|
406 |
+
return returnValue;
|
407 |
+
};
|
408 |
+
})();
|
409 |
+
});
|
410 |
+
constructor.prototype = $.widget.extend( basePrototype, {
|
411 |
+
// TODO: remove support for widgetEventPrefix
|
412 |
+
// always use the name + a colon as the prefix, e.g., draggable:start
|
413 |
+
// don't prefix for widgets that aren't DOM-based
|
414 |
+
widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
|
415 |
+
}, proxiedPrototype, {
|
416 |
+
constructor: constructor,
|
417 |
namespace: namespace,
|
418 |
widgetName: name,
|
419 |
+
widgetFullName: fullName
|
420 |
+
});
|
421 |
+
|
422 |
+
// If this widget is being redefined then we need to find all widgets that
|
423 |
+
// are inheriting from it and redefine all of them so that they inherit from
|
424 |
+
// the new version of this widget. We're essentially trying to replace one
|
425 |
+
// level in the prototype chain.
|
426 |
+
if ( existingConstructor ) {
|
427 |
+
$.each( existingConstructor._childConstructors, function( i, child ) {
|
428 |
+
var childPrototype = child.prototype;
|
429 |
+
|
430 |
+
// redefine the child widget using the same prototype that was
|
431 |
+
// originally used, but inherit from the new version of the base
|
432 |
+
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
|
433 |
+
});
|
434 |
+
// remove the list of existing child constructors from the old constructor
|
435 |
+
// so the old child constructors can be garbage collected
|
436 |
+
delete existingConstructor._childConstructors;
|
437 |
+
} else {
|
438 |
+
base._childConstructors.push( constructor );
|
439 |
+
}
|
440 |
+
|
441 |
+
$.widget.bridge( name, constructor );
|
442 |
+
};
|
443 |
|
444 |
+
$.widget.extend = function( target ) {
|
445 |
+
var input = slice.call( arguments, 1 ),
|
446 |
+
inputIndex = 0,
|
447 |
+
inputLength = input.length,
|
448 |
+
key,
|
449 |
+
value;
|
450 |
+
for ( ; inputIndex < inputLength; inputIndex++ ) {
|
451 |
+
for ( key in input[ inputIndex ] ) {
|
452 |
+
value = input[ inputIndex ][ key ];
|
453 |
+
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
|
454 |
+
// Clone objects
|
455 |
+
if ( $.isPlainObject( value ) ) {
|
456 |
+
target[ key ] = $.isPlainObject( target[ key ] ) ?
|
457 |
+
$.widget.extend( {}, target[ key ], value ) :
|
458 |
+
// Don't extend strings, arrays, etc. with objects
|
459 |
+
$.widget.extend( {}, value );
|
460 |
+
// Copy everything else by reference
|
461 |
+
} else {
|
462 |
+
target[ key ] = value;
|
463 |
+
}
|
464 |
+
}
|
465 |
+
}
|
466 |
+
}
|
467 |
+
return target;
|
468 |
};
|
469 |
|
470 |
$.widget.bridge = function( name, object ) {
|
471 |
+
var fullName = object.prototype.widgetFullName || name;
|
472 |
$.fn[ name ] = function( options ) {
|
473 |
var isMethodCall = typeof options === "string",
|
474 |
+
args = slice.call( arguments, 1 ),
|
475 |
returnValue = this;
|
476 |
|
477 |
// allow multiple hashes to be passed on init
|
478 |
options = !isMethodCall && args.length ?
|
479 |
+
$.widget.extend.apply( null, [ options ].concat(args) ) :
|
480 |
options;
|
481 |
|
|
|
|
|
|
|
|
|
|
|
482 |
if ( isMethodCall ) {
|
483 |
this.each(function() {
|
484 |
+
var methodValue,
|
485 |
+
instance = $.data( this, fullName );
|
486 |
+
if ( !instance ) {
|
487 |
+
return $.error( "cannot call methods on " + name + " prior to initialization; " +
|
488 |
+
"attempted to call method '" + options + "'" );
|
489 |
+
}
|
490 |
+
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
|
491 |
+
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
|
492 |
+
}
|
493 |
+
methodValue = instance[ options ].apply( instance, args );
|
|
|
|
|
|
|
494 |
if ( methodValue !== instance && methodValue !== undefined ) {
|
495 |
+
returnValue = methodValue && methodValue.jquery ?
|
496 |
+
returnValue.pushStack( methodValue.get() ) :
|
497 |
+
methodValue;
|
498 |
return false;
|
499 |
}
|
500 |
});
|
501 |
} else {
|
502 |
this.each(function() {
|
503 |
+
var instance = $.data( this, fullName );
|
504 |
if ( instance ) {
|
505 |
instance.option( options || {} )._init();
|
506 |
} else {
|
507 |
+
$.data( this, fullName, new object( options, this ) );
|
508 |
}
|
509 |
});
|
510 |
}
|
513 |
};
|
514 |
};
|
515 |
|
516 |
+
$.Widget = function( /* options, element */ ) {};
|
517 |
+
$.Widget._childConstructors = [];
|
|
|
|
|
|
|
|
|
518 |
|
519 |
$.Widget.prototype = {
|
520 |
widgetName: "widget",
|
521 |
widgetEventPrefix: "",
|
522 |
+
defaultElement: "<div>",
|
523 |
options: {
|
524 |
+
disabled: false,
|
525 |
+
|
526 |
+
// callbacks
|
527 |
+
create: null
|
528 |
},
|
529 |
_createWidget: function( options, element ) {
|
530 |
+
element = $( element || this.defaultElement || this )[ 0 ];
|
|
|
|
|
531 |
this.element = $( element );
|
532 |
+
this.uuid = uuid++;
|
533 |
+
this.eventNamespace = "." + this.widgetName + this.uuid;
|
534 |
+
this.options = $.widget.extend( {},
|
535 |
this.options,
|
536 |
this._getCreateOptions(),
|
537 |
options );
|
538 |
|
539 |
+
this.bindings = $();
|
540 |
+
this.hoverable = $();
|
541 |
+
this.focusable = $();
|
542 |
+
|
543 |
+
if ( element !== this ) {
|
544 |
+
$.data( element, this.widgetFullName, this );
|
545 |
+
this._on( true, this.element, {
|
546 |
+
remove: function( event ) {
|
547 |
+
if ( event.target === element ) {
|
548 |
+
this.destroy();
|
549 |
+
}
|
550 |
+
}
|
551 |
+
});
|
552 |
+
this.document = $( element.style ?
|
553 |
+
// element within the document
|
554 |
+
element.ownerDocument :
|
555 |
+
// element is window or document
|
556 |
+
element.document || element );
|
557 |
+
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
|
558 |
+
}
|
559 |
|
560 |
this._create();
|
561 |
+
this._trigger( "create", null, this._getCreateEventData() );
|
562 |
this._init();
|
563 |
},
|
564 |
+
_getCreateOptions: $.noop,
|
565 |
+
_getCreateEventData: $.noop,
|
566 |
+
_create: $.noop,
|
567 |
+
_init: $.noop,
|
|
|
568 |
|
569 |
destroy: function() {
|
570 |
+
this._destroy();
|
571 |
+
// we can probably remove the unbind calls in 2.0
|
572 |
+
// all event bindings should go through this._on()
|
573 |
this.element
|
574 |
+
.unbind( this.eventNamespace )
|
575 |
+
// 1.9 BC for #7810
|
576 |
+
// TODO remove dual storage
|
577 |
+
.removeData( this.widgetName )
|
578 |
+
.removeData( this.widgetFullName )
|
579 |
+
// support: jquery <1.6.3
|
580 |
+
// http://bugs.jquery.com/ticket/9413
|
581 |
+
.removeData( $.camelCase( this.widgetFullName ) );
|
582 |
this.widget()
|
583 |
+
.unbind( this.eventNamespace )
|
584 |
.removeAttr( "aria-disabled" )
|
585 |
.removeClass(
|
586 |
+
this.widgetFullName + "-disabled " +
|
587 |
"ui-state-disabled" );
|
588 |
+
|
589 |
+
// clean up events and states
|
590 |
+
this.bindings.unbind( this.eventNamespace );
|
591 |
+
this.hoverable.removeClass( "ui-state-hover" );
|
592 |
+
this.focusable.removeClass( "ui-state-focus" );
|
593 |
},
|
594 |
+
_destroy: $.noop,
|
595 |
|
596 |
widget: function() {
|
597 |
return this.element;
|
598 |
},
|
599 |
|
600 |
option: function( key, value ) {
|
601 |
+
var options = key,
|
602 |
+
parts,
|
603 |
+
curOption,
|
604 |
+
i;
|
605 |
|
606 |
if ( arguments.length === 0 ) {
|
607 |
// don't return a reference to the internal hash
|
608 |
+
return $.widget.extend( {}, this.options );
|
609 |
}
|
610 |
|
611 |
+
if ( typeof key === "string" ) {
|
612 |
+
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
|
|
|
|
|
613 |
options = {};
|
614 |
+
parts = key.split( "." );
|
615 |
+
key = parts.shift();
|
616 |
+
if ( parts.length ) {
|
617 |
+
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
|
618 |
+
for ( i = 0; i < parts.length - 1; i++ ) {
|
619 |
+
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
|
620 |
+
curOption = curOption[ parts[ i ] ];
|
621 |
+
}
|
622 |
+
key = parts.pop();
|
623 |
+
if ( value === undefined ) {
|
624 |
+
return curOption[ key ] === undefined ? null : curOption[ key ];
|
625 |
+
}
|
626 |
+
curOption[ key ] = value;
|
627 |
+
} else {
|
628 |
+
if ( value === undefined ) {
|
629 |
+
return this.options[ key ] === undefined ? null : this.options[ key ];
|
630 |
+
}
|
631 |
+
options[ key ] = value;
|
632 |
+
}
|
633 |
}
|
634 |
|
635 |
this._setOptions( options );
|
637 |
return this;
|
638 |
},
|
639 |
_setOptions: function( options ) {
|
640 |
+
var key;
|
641 |
+
|
642 |
+
for ( key in options ) {
|
643 |
+
this._setOption( key, options[ key ] );
|
644 |
+
}
|
645 |
|
646 |
return this;
|
647 |
},
|
650 |
|
651 |
if ( key === "disabled" ) {
|
652 |
this.widget()
|
653 |
+
.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
|
|
|
|
|
654 |
.attr( "aria-disabled", value );
|
655 |
+
this.hoverable.removeClass( "ui-state-hover" );
|
656 |
+
this.focusable.removeClass( "ui-state-focus" );
|
657 |
}
|
658 |
|
659 |
return this;
|
666 |
return this._setOption( "disabled", true );
|
667 |
},
|
668 |
|
669 |
+
_on: function( suppressDisabledCheck, element, handlers ) {
|
670 |
+
var delegateElement,
|
671 |
+
instance = this;
|
672 |
+
|
673 |
+
// no suppressDisabledCheck flag, shuffle arguments
|
674 |
+
if ( typeof suppressDisabledCheck !== "boolean" ) {
|
675 |
+
handlers = element;
|
676 |
+
element = suppressDisabledCheck;
|
677 |
+
suppressDisabledCheck = false;
|
678 |
+
}
|
679 |
+
|
680 |
+
// no element argument, shuffle and use this.element
|
681 |
+
if ( !handlers ) {
|
682 |
+
handlers = element;
|
683 |
+
element = this.element;
|
684 |
+
delegateElement = this.widget();
|
685 |
+
} else {
|
686 |
+
// accept selectors, DOM elements
|
687 |
+
element = delegateElement = $( element );
|
688 |
+
this.bindings = this.bindings.add( element );
|
689 |
+
}
|
690 |
+
|
691 |
+
$.each( handlers, function( event, handler ) {
|
692 |
+
function handlerProxy() {
|
693 |
+
// allow widgets to customize the disabled handling
|
694 |
+
// - disabled as an array instead of boolean
|
695 |
+
// - disabled class as method for disabling individual parts
|
696 |
+
if ( !suppressDisabledCheck &&
|
697 |
+
( instance.options.disabled === true ||
|
698 |
+
$( this ).hasClass( "ui-state-disabled" ) ) ) {
|
699 |
+
return;
|
700 |
+
}
|
701 |
+
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
702 |
+
.apply( instance, arguments );
|
703 |
+
}
|
704 |
+
|
705 |
+
// copy the guid so direct unbinding works
|
706 |
+
if ( typeof handler !== "string" ) {
|
707 |
+
handlerProxy.guid = handler.guid =
|
708 |
+
handler.guid || handlerProxy.guid || $.guid++;
|
709 |
+
}
|
710 |
+
|
711 |
+
var match = event.match( /^(\w+)\s*(.*)$/ ),
|
712 |
+
eventName = match[1] + instance.eventNamespace,
|
713 |
+
selector = match[2];
|
714 |
+
if ( selector ) {
|
715 |
+
delegateElement.delegate( selector, eventName, handlerProxy );
|
716 |
+
} else {
|
717 |
+
element.bind( eventName, handlerProxy );
|
718 |
+
}
|
719 |
+
});
|
720 |
+
},
|
721 |
+
|
722 |
+
_off: function( element, eventName ) {
|
723 |
+
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
|
724 |
+
element.unbind( eventName ).undelegate( eventName );
|
725 |
+
},
|
726 |
+
|
727 |
+
_delay: function( handler, delay ) {
|
728 |
+
function handlerProxy() {
|
729 |
+
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
730 |
+
.apply( instance, arguments );
|
731 |
+
}
|
732 |
+
var instance = this;
|
733 |
+
return setTimeout( handlerProxy, delay || 0 );
|
734 |
+
},
|
735 |
+
|
736 |
+
_hoverable: function( element ) {
|
737 |
+
this.hoverable = this.hoverable.add( element );
|
738 |
+
this._on( element, {
|
739 |
+
mouseenter: function( event ) {
|
740 |
+
$( event.currentTarget ).addClass( "ui-state-hover" );
|
741 |
+
},
|
742 |
+
mouseleave: function( event ) {
|
743 |
+
$( event.currentTarget ).removeClass( "ui-state-hover" );
|
744 |
+
}
|
745 |
+
});
|
746 |
+
},
|
747 |
+
|
748 |
+
_focusable: function( element ) {
|
749 |
+
this.focusable = this.focusable.add( element );
|
750 |
+
this._on( element, {
|
751 |
+
focusin: function( event ) {
|
752 |
+
$( event.currentTarget ).addClass( "ui-state-focus" );
|
753 |
+
},
|
754 |
+
focusout: function( event ) {
|
755 |
+
$( event.currentTarget ).removeClass( "ui-state-focus" );
|
756 |
+
}
|
757 |
+
});
|
758 |
+
},
|
759 |
+
|
760 |
_trigger: function( type, event, data ) {
|
761 |
var prop, orig,
|
762 |
callback = this.options[ type ];
|
781 |
}
|
782 |
|
783 |
this.element.trigger( event, data );
|
784 |
+
return !( $.isFunction( callback ) &&
|
785 |
+
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
|
|
|
786 |
event.isDefaultPrevented() );
|
787 |
}
|
788 |
};
|
789 |
|
790 |
+
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
|
791 |
+
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
|
792 |
+
if ( typeof options === "string" ) {
|
793 |
+
options = { effect: options };
|
794 |
+
}
|
795 |
+
var hasOptions,
|
796 |
+
effectName = !options ?
|
797 |
+
method :
|
798 |
+
options === true || typeof options === "number" ?
|
799 |
+
defaultEffect :
|
800 |
+
options.effect || defaultEffect;
|
801 |
+
options = options || {};
|
802 |
+
if ( typeof options === "number" ) {
|
803 |
+
options = { duration: options };
|
804 |
+
}
|
805 |
+
hasOptions = !$.isEmptyObject( options );
|
806 |
+
options.complete = callback;
|
807 |
+
if ( options.delay ) {
|
808 |
+
element.delay( options.delay );
|
809 |
+
}
|
810 |
+
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
|
811 |
+
element[ method ]( options );
|
812 |
+
} else if ( effectName !== method && element[ effectName ] ) {
|
813 |
+
element[ effectName ]( options.duration, options.easing, callback );
|
814 |
+
} else {
|
815 |
+
element.queue(function( next ) {
|
816 |
+
$( this )[ method ]();
|
817 |
+
if ( callback ) {
|
818 |
+
callback.call( element[ 0 ] );
|
819 |
+
}
|
820 |
+
next();
|
821 |
+
});
|
822 |
+
}
|
823 |
+
};
|
824 |
+
});
|
825 |
+
|
826 |
})( jQuery );
|
827 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
828 |
(function( $, undefined ) {
|
829 |
|
830 |
var mouseHandled = false;
|
831 |
+
$( document ).mouseup( function() {
|
832 |
mouseHandled = false;
|
833 |
});
|
834 |
|
835 |
$.widget("ui.mouse", {
|
836 |
+
version: "1.10.2",
|
837 |
options: {
|
838 |
+
cancel: "input,textarea,button,select,option",
|
839 |
distance: 1,
|
840 |
delay: 0
|
841 |
},
|
842 |
_mouseInit: function() {
|
843 |
+
var that = this;
|
844 |
|
845 |
this.element
|
846 |
+
.bind("mousedown."+this.widgetName, function(event) {
|
847 |
+
return that._mouseDown(event);
|
848 |
})
|
849 |
+
.bind("click."+this.widgetName, function(event) {
|
850 |
+
if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
|
851 |
+
$.removeData(event.target, that.widgetName + ".preventClickEvent");
|
852 |
event.stopImmediatePropagation();
|
853 |
return false;
|
854 |
}
|
860 |
// TODO: make sure destroying one instance of mouse doesn't mess with
|
861 |
// other instances of mouse
|
862 |
_mouseDestroy: function() {
|
863 |
+
this.element.unbind("."+this.widgetName);
|
864 |
+
if ( this._mouseMoveDelegate ) {
|
865 |
+
$(document)
|
866 |
+
.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
|
867 |
+
.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
|
868 |
+
}
|
869 |
},
|
870 |
|
871 |
_mouseDown: function(event) {
|
872 |
// don't let more than one widget handle mouseStart
|
873 |
+
if( mouseHandled ) { return; }
|
874 |
|
875 |
// we may have missed mouseup (out of window)
|
876 |
(this._mouseStarted && this._mouseUp(event));
|
877 |
|
878 |
this._mouseDownEvent = event;
|
879 |
|
880 |
+
var that = this,
|
881 |
+
btnIsLeft = (event.which === 1),
|
882 |
// event.target.nodeName works around a bug in IE 8 with
|
883 |
// disabled inputs (#7620)
|
884 |
+
elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
|
885 |
if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
|
886 |
return true;
|
887 |
}
|
889 |
this.mouseDelayMet = !this.options.delay;
|
890 |
if (!this.mouseDelayMet) {
|
891 |
this._mouseDelayTimer = setTimeout(function() {
|
892 |
+
that.mouseDelayMet = true;
|
893 |
}, this.options.delay);
|
894 |
}
|
895 |
|
902 |
}
|
903 |
|
904 |
// Click event may never have fired (Gecko & Opera)
|
905 |
+
if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
|
906 |
+
$.removeData(event.target, this.widgetName + ".preventClickEvent");
|
907 |
}
|
908 |
|
909 |
// these delegates are required to keep context
|
910 |
this._mouseMoveDelegate = function(event) {
|
911 |
+
return that._mouseMove(event);
|
912 |
};
|
913 |
this._mouseUpDelegate = function(event) {
|
914 |
+
return that._mouseUp(event);
|
915 |
};
|
916 |
$(document)
|
917 |
+
.bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
|
918 |
+
.bind("mouseup."+this.widgetName, this._mouseUpDelegate);
|
919 |
|
920 |
event.preventDefault();
|
921 |
+
|
922 |
mouseHandled = true;
|
923 |
return true;
|
924 |
},
|
925 |
|
926 |
_mouseMove: function(event) {
|
927 |
// IE mouseup check - mouseup happened when mouse was out of window
|
928 |
+
if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
|
929 |
return this._mouseUp(event);
|
930 |
}
|
931 |
|
945 |
|
946 |
_mouseUp: function(event) {
|
947 |
$(document)
|
948 |
+
.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
|
949 |
+
.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
|
950 |
|
951 |
if (this._mouseStarted) {
|
952 |
this._mouseStarted = false;
|
953 |
|
954 |
+
if (event.target === this._mouseDownEvent.target) {
|
955 |
+
$.data(event.target, this.widgetName + ".preventClickEvent", true);
|
956 |
}
|
957 |
|
958 |
this._mouseStop(event);
|
969 |
);
|
970 |
},
|
971 |
|
972 |
+
_mouseDelayMet: function(/* event */) {
|
973 |
return this.mouseDelayMet;
|
974 |
},
|
975 |
|
976 |
// These are placeholder methods, to be overriden by extending plugin
|
977 |
+
_mouseStart: function(/* event */) {},
|
978 |
+
_mouseDrag: function(/* event */) {},
|
979 |
+
_mouseStop: function(/* event */) {},
|
980 |
+
_mouseCapture: function(/* event */) { return true; }
|
981 |
});
|
982 |
|
983 |
})(jQuery);
|
984 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
985 |
(function( $, undefined ) {
|
986 |
|
987 |
+
$.widget("ui.draggable", $.ui.mouse, {
|
988 |
+
version: "1.10.2",
|
989 |
+
widgetEventPrefix: "drag",
|
990 |
+
options: {
|
991 |
+
addClasses: true,
|
992 |
+
appendTo: "parent",
|
993 |
+
axis: false,
|
994 |
+
connectToSortable: false,
|
995 |
+
containment: false,
|
996 |
+
cursor: "auto",
|
997 |
+
cursorAt: false,
|
998 |
+
grid: false,
|
999 |
+
handle: false,
|
1000 |
+
helper: "original",
|
1001 |
+
iframeFix: false,
|
1002 |
+
opacity: false,
|
1003 |
+
refreshPositions: false,
|
1004 |
+
revert: false,
|
1005 |
+
revertDuration: 500,
|
1006 |
+
scope: "default",
|
1007 |
+
scroll: true,
|
1008 |
+
scrollSensitivity: 20,
|
1009 |
+
scrollSpeed: 20,
|
1010 |
+
snap: false,
|
1011 |
+
snapMode: "both",
|
1012 |
+
snapTolerance: 20,
|
1013 |
+
stack: false,
|
1014 |
+
zIndex: false,
|
1015 |
|
1016 |
+
// callbacks
|
1017 |
+
drag: null,
|
1018 |
+
start: null,
|
1019 |
+
stop: null
|
1020 |
+
},
|
1021 |
+
_create: function() {
|
1022 |
|
1023 |
+
if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
|
1024 |
+
this.element[0].style.position = "relative";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1025 |
}
|
1026 |
+
if (this.options.addClasses){
|
1027 |
+
this.element.addClass("ui-draggable");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1028 |
}
|
1029 |
+
if (this.options.disabled){
|
1030 |
+
this.element.addClass("ui-draggable-disabled");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1031 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1032 |
|
1033 |
this._mouseInit();
|
1034 |
|
1035 |
},
|
1036 |
|
1037 |
+
_destroy: function() {
|
1038 |
+
this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
|
|
|
|
|
|
|
|
|
|
|
|
|
1039 |
this._mouseDestroy();
|
|
|
|
|
1040 |
},
|
1041 |
|
1042 |
_mouseCapture: function(event) {
|
1044 |
var o = this.options;
|
1045 |
|
1046 |
// among others, prevent a drag on a resizable-handle
|
1047 |
+
if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
|
1048 |
return false;
|
1049 |
+
}
|
1050 |
|
1051 |
//Quit if we're not on a valid handle
|
1052 |
this.handle = this._getHandle(event);
|
1053 |
+
if (!this.handle) {
|
1054 |
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1055 |
}
|
1056 |
|
1057 |
+
$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
|
1058 |
+
$("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
|
1059 |
+
.css({
|
1060 |
+
width: this.offsetWidth+"px", height: this.offsetHeight+"px",
|
1061 |
+
position: "absolute", opacity: "0.001", zIndex: 1000
|
1062 |
+
})
|
1063 |
+
.css($(this).offset())
|
1064 |
+
.appendTo("body");
|
1065 |
+
});
|
1066 |
+
|
1067 |
return true;
|
1068 |
|
1069 |
},
|
1075 |
//Create and append the visible helper
|
1076 |
this.helper = this._createHelper(event);
|
1077 |
|
1078 |
+
this.helper.addClass("ui-draggable-dragging");
|
1079 |
+
|
1080 |
//Cache the helper size
|
1081 |
this._cacheHelperProportions();
|
1082 |
|
1083 |
//If ddmanager is used for droppables, set the global draggable
|
1084 |
+
if($.ui.ddmanager) {
|
1085 |
$.ui.ddmanager.current = this;
|
1086 |
+
}
|
1087 |
|
1088 |
/*
|
1089 |
* - Position generation -
|
1118 |
this.originalPageX = event.pageX;
|
1119 |
this.originalPageY = event.pageY;
|
1120 |
|
1121 |
+
//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
|
1122 |
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
|
1123 |
|
1124 |
//Set a containment if given in the options
|
1125 |
+
if(o.containment) {
|
1126 |
this._setContainment();
|
1127 |
+
}
|
1128 |
|
1129 |
//Trigger event + callbacks
|
1130 |
if(this._trigger("start", event) === false) {
|
1136 |
this._cacheHelperProportions();
|
1137 |
|
1138 |
//Prepare the droppable offsets
|
1139 |
+
if ($.ui.ddmanager && !o.dropBehaviour) {
|
1140 |
$.ui.ddmanager.prepareOffsets(this, event);
|
1141 |
+
}
|
1142 |
+
|
1143 |
|
|
|
1144 |
this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
|
1145 |
+
|
1146 |
//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
|
1147 |
+
if ( $.ui.ddmanager ) {
|
1148 |
+
$.ui.ddmanager.dragStart(this, event);
|
1149 |
+
}
|
1150 |
+
|
1151 |
return true;
|
1152 |
},
|
1153 |
|
1160 |
//Call plugins and callbacks and use the resulting position if something is returned
|
1161 |
if (!noPropagation) {
|
1162 |
var ui = this._uiHash();
|
1163 |
+
if(this._trigger("drag", event, ui) === false) {
|
1164 |
this._mouseUp({});
|
1165 |
return false;
|
1166 |
}
|
1167 |
this.position = ui.position;
|
1168 |
}
|
1169 |
|
1170 |
+
if(!this.options.axis || this.options.axis !== "y") {
|
1171 |
+
this.helper[0].style.left = this.position.left+"px";
|
1172 |
+
}
|
1173 |
+
if(!this.options.axis || this.options.axis !== "x") {
|
1174 |
+
this.helper[0].style.top = this.position.top+"px";
|
1175 |
+
}
|
1176 |
+
if($.ui.ddmanager) {
|
1177 |
+
$.ui.ddmanager.drag(this, event);
|
1178 |
+
}
|
1179 |
|
1180 |
return false;
|
1181 |
},
|
1183 |
_mouseStop: function(event) {
|
1184 |
|
1185 |
//If we are using droppables, inform the manager about the drop
|
1186 |
+
var element,
|
1187 |
+
that = this,
|
1188 |
+
elementInDom = false,
|
1189 |
+
dropped = false;
|
1190 |
+
if ($.ui.ddmanager && !this.options.dropBehaviour) {
|
1191 |
dropped = $.ui.ddmanager.drop(this, event);
|
1192 |
+
}
|
1193 |
|
1194 |
//if a drop comes from outside (a sortable)
|
1195 |
if(this.dropped) {
|
1196 |
dropped = this.dropped;
|
1197 |
this.dropped = false;
|
1198 |
}
|
1199 |
+
|
1200 |
+
//if the original element is no longer in the DOM don't bother to continue (see #8269)
|
1201 |
+
element = this.element[0];
|
1202 |
+
while ( element && (element = element.parentNode) ) {
|
1203 |
+
if (element === document ) {
|
1204 |
+
elementInDom = true;
|
1205 |
+
}
|
1206 |
+
}
|
1207 |
+
if ( !elementInDom && this.options.helper === "original" ) {
|
1208 |
return false;
|
1209 |
+
}
|
1210 |
|
1211 |
+
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))) {
|
|
|
1212 |
$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
|
1213 |
+
if(that._trigger("stop", event) !== false) {
|
1214 |
+
that._clear();
|
1215 |
}
|
1216 |
});
|
1217 |
} else {
|
1222 |
|
1223 |
return false;
|
1224 |
},
|
1225 |
+
|
1226 |
_mouseUp: function(event) {
|
1227 |
+
//Remove frame helpers
|
1228 |
+
$("div.ui-draggable-iframeFix").each(function() {
|
1229 |
+
this.parentNode.removeChild(this);
|
1230 |
+
});
|
1231 |
+
|
|
|
1232 |
//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
|
1233 |
+
if( $.ui.ddmanager ) {
|
1234 |
+
$.ui.ddmanager.dragStop(this, event);
|
1235 |
+
}
|
1236 |
+
|
1237 |
return $.ui.mouse.prototype._mouseUp.call(this, event);
|
1238 |
},
|
1239 |
+
|
1240 |
cancel: function() {
|
1241 |
+
|
1242 |
if(this.helper.is(".ui-draggable-dragging")) {
|
1243 |
this._mouseUp({});
|
1244 |
} else {
|
1245 |
this._clear();
|
1246 |
}
|
1247 |
+
|
1248 |
return this;
|
1249 |
+
|
1250 |
},
|
1251 |
|
1252 |
_getHandle: function(event) {
|
1253 |
+
return this.options.handle ?
|
1254 |
+
!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
|
1255 |
+
true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1256 |
},
|
1257 |
|
1258 |
_createHelper: function(event) {
|
1259 |
|
1260 |
+
var o = this.options,
|
1261 |
+
helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
|
1262 |
|
1263 |
+
if(!helper.parents("body").length) {
|
1264 |
+
helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
|
1265 |
+
}
|
1266 |
|
1267 |
+
if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
|
1268 |
helper.css("position", "absolute");
|
1269 |
+
}
|
1270 |
|
1271 |
return helper;
|
1272 |
|
1273 |
},
|
1274 |
|
1275 |
_adjustOffsetFromHelper: function(obj) {
|
1276 |
+
if (typeof obj === "string") {
|
1277 |
+
obj = obj.split(" ");
|
1278 |
}
|
1279 |
if ($.isArray(obj)) {
|
1280 |
obj = {left: +obj[0], top: +obj[1] || 0};
|
1281 |
}
|
1282 |
+
if ("left" in obj) {
|
1283 |
this.offset.click.left = obj.left + this.margins.left;
|
1284 |
}
|
1285 |
+
if ("right" in obj) {
|
1286 |
this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
|
1287 |
}
|
1288 |
+
if ("top" in obj) {
|
1289 |
this.offset.click.top = obj.top + this.margins.top;
|
1290 |
}
|
1291 |
+
if ("bottom" in obj) {
|
1292 |
this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
|
1293 |
}
|
1294 |
},
|
1303 |
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
|
1304 |
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
|
1305 |
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
|
1306 |
+
if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
|
1307 |
po.left += this.scrollParent.scrollLeft();
|
1308 |
po.top += this.scrollParent.scrollTop();
|
1309 |
}
|
1310 |
|
1311 |
+
//This needs to be actually done for all browsers, since pageX/pageY includes this information
|
1312 |
+
//Ugly IE fix
|
1313 |
+
if((this.offsetParent[0] === document.body) ||
|
1314 |
+
(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
|
1315 |
po = { top: 0, left: 0 };
|
1316 |
+
}
|
1317 |
|
1318 |
return {
|
1319 |
top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
|
1324 |
|
1325 |
_getRelativeOffset: function() {
|
1326 |
|
1327 |
+
if(this.cssPosition === "relative") {
|
1328 |
var p = this.element.position();
|
1329 |
return {
|
1330 |
top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
|
1354 |
|
1355 |
_setContainment: function() {
|
1356 |
|
1357 |
+
var over, c, ce,
|
1358 |
+
o = this.options;
|
1359 |
+
|
1360 |
+
if(o.containment === "parent") {
|
1361 |
+
o.containment = this.helper[0].parentNode;
|
1362 |
+
}
|
1363 |
+
if(o.containment === "document" || o.containment === "window") {
|
1364 |
+
this.containment = [
|
1365 |
+
o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
|
1366 |
+
o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
|
1367 |
+
(o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
|
1368 |
+
(o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
|
1369 |
+
];
|
1370 |
+
}
|
1371 |
|
1372 |
+
if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
|
1373 |
+
c = $(o.containment);
|
1374 |
+
ce = c[0];
|
1375 |
+
|
1376 |
+
if(!ce) {
|
1377 |
+
return;
|
1378 |
+
}
|
1379 |
+
|
1380 |
+
over = ($(ce).css("overflow") !== "hidden");
|
1381 |
|
1382 |
this.containment = [
|
1383 |
(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
|
1384 |
(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
|
1385 |
+
(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderRightWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
|
1386 |
+
(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderBottomWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom
|
1387 |
];
|
1388 |
this.relative_container = c;
|
1389 |
|
1390 |
+
} else if(o.containment.constructor === Array) {
|
1391 |
this.containment = o.containment;
|
1392 |
}
|
1393 |
|
1395 |
|
1396 |
_convertPositionTo: function(d, pos) {
|
1397 |
|
1398 |
+
if(!pos) {
|
1399 |
+
pos = this.position;
|
1400 |
+
}
|
1401 |
+
|
1402 |
+
var mod = d === "absolute" ? 1 : -1,
|
1403 |
+
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);
|
1404 |
|
1405 |
return {
|
1406 |
top: (
|
1407 |
+
pos.top + // The absolute mouse position
|
1408 |
+
this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
|
1409 |
+
this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
|
1410 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
|
1411 |
),
|
1412 |
left: (
|
1413 |
+
pos.left + // The absolute mouse position
|
1414 |
+
this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
|
1415 |
+
this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
|
1416 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
|
1417 |
)
|
1418 |
};
|
1419 |
|
1421 |
|
1422 |
_generatePosition: function(event) {
|
1423 |
|
1424 |
+
var containment, co, top, left,
|
1425 |
+
o = this.options,
|
1426 |
+
scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
|
1427 |
+
scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
|
1428 |
+
pageX = event.pageX,
|
1429 |
+
pageY = event.pageY;
|
1430 |
|
1431 |
/*
|
1432 |
* - Position constraining -
|
1434 |
*/
|
1435 |
|
1436 |
if(this.originalPosition) { //If we are not dragging yet, we won't check for options
|
1437 |
+
if(this.containment) {
|
1438 |
+
if (this.relative_container){
|
1439 |
+
co = this.relative_container.offset();
|
1440 |
+
containment = [ this.containment[0] + co.left,
|
1441 |
+
this.containment[1] + co.top,
|
1442 |
+
this.containment[2] + co.left,
|
1443 |
+
this.containment[3] + co.top ];
|
1444 |
+
}
|
1445 |
+
else {
|
1446 |
+
containment = this.containment;
|
1447 |
+
}
|
1448 |
+
|
1449 |
+
if(event.pageX - this.offset.click.left < containment[0]) {
|
1450 |
+
pageX = containment[0] + this.offset.click.left;
|
1451 |
+
}
|
1452 |
+
if(event.pageY - this.offset.click.top < containment[1]) {
|
1453 |
+
pageY = containment[1] + this.offset.click.top;
|
1454 |
+
}
|
1455 |
+
if(event.pageX - this.offset.click.left > containment[2]) {
|
1456 |
+
pageX = containment[2] + this.offset.click.left;
|
1457 |
+
}
|
1458 |
+
if(event.pageY - this.offset.click.top > containment[3]) {
|
1459 |
+
pageY = containment[3] + this.offset.click.top;
|
1460 |
+
}
|
1461 |
}
|
1462 |
|
1463 |
if(o.grid) {
|
1464 |
//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
|
1465 |
+
top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
|
1466 |
+
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;
|
1467 |
|
1468 |
+
left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
|
1469 |
+
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;
|
1470 |
}
|
1471 |
|
1472 |
}
|
1473 |
|
1474 |
return {
|
1475 |
top: (
|
1476 |
+
pageY - // The absolute mouse position
|
1477 |
+
this.offset.click.top - // Click offset (relative to the element)
|
1478 |
+
this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
|
1479 |
+
this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
|
1480 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
|
1481 |
),
|
1482 |
left: (
|
1483 |
+
pageX - // The absolute mouse position
|
1484 |
+
this.offset.click.left - // Click offset (relative to the element)
|
1485 |
+
this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
|
1486 |
+
this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
|
1487 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
|
1488 |
)
|
1489 |
};
|
1490 |
|
1492 |
|
1493 |
_clear: function() {
|
1494 |
this.helper.removeClass("ui-draggable-dragging");
|
1495 |
+
if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
|
1496 |
+
this.helper.remove();
|
1497 |
+
}
|
1498 |
this.helper = null;
|
1499 |
this.cancelHelperRemoval = false;
|
1500 |
},
|
1504 |
_trigger: function(type, event, ui) {
|
1505 |
ui = ui || this._uiHash();
|
1506 |
$.ui.plugin.call(this, type, [event, ui]);
|
1507 |
+
//The absolute position has to be recalculated after plugins
|
1508 |
+
if(type === "drag") {
|
1509 |
+
this.positionAbs = this._convertPositionTo("absolute");
|
1510 |
+
}
|
1511 |
return $.Widget.prototype._trigger.call(this, type, event, ui);
|
1512 |
},
|
1513 |
|
1514 |
plugins: {},
|
1515 |
|
1516 |
+
_uiHash: function() {
|
1517 |
return {
|
1518 |
helper: this.helper,
|
1519 |
position: this.position,
|
1524 |
|
1525 |
});
|
1526 |
|
|
|
|
|
|
|
|
|
1527 |
$.ui.plugin.add("draggable", "connectToSortable", {
|
1528 |
start: function(event, ui) {
|
1529 |
|
1530 |
+
var inst = $(this).data("ui-draggable"), o = inst.options,
|
1531 |
uiSortable = $.extend({}, ui, { item: inst.element });
|
1532 |
inst.sortables = [];
|
1533 |
$(o.connectToSortable).each(function() {
|
1534 |
+
var sortable = $.data(this, "ui-sortable");
|
1535 |
if (sortable && !sortable.options.disabled) {
|
1536 |
inst.sortables.push({
|
1537 |
instance: sortable,
|
1546 |
stop: function(event, ui) {
|
1547 |
|
1548 |
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
|
1549 |
+
var inst = $(this).data("ui-draggable"),
|
1550 |
uiSortable = $.extend({}, ui, { item: inst.element });
|
1551 |
|
1552 |
$.each(inst.sortables, function() {
|
1557 |
inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
|
1558 |
this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
|
1559 |
|
1560 |
+
//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
|
1561 |
+
if(this.shouldRevert) {
|
1562 |
+
this.instance.options.revert = this.shouldRevert;
|
1563 |
+
}
|
1564 |
|
1565 |
//Trigger the stop of the sortable
|
1566 |
this.instance._mouseStop(event);
|
1568 |
this.instance.options.helper = this.instance.options._helper;
|
1569 |
|
1570 |
//If the helper has been the original item, restore properties in the sortable
|
1571 |
+
if(inst.options.helper === "original") {
|
1572 |
+
this.instance.currentItem.css({ top: "auto", left: "auto" });
|
1573 |
+
}
|
1574 |
|
1575 |
} else {
|
1576 |
this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
|
1582 |
},
|
1583 |
drag: function(event, ui) {
|
1584 |
|
1585 |
+
var inst = $(this).data("ui-draggable"), that = this;
|
1586 |
|
1587 |
+
$.each(inst.sortables, function() {
|
|
|
|
|
|
|
|
|
1588 |
|
1589 |
+
var innermostIntersecting = false,
|
1590 |
+
thisSortable = this;
|
1591 |
|
|
|
|
|
1592 |
//Copy over some variables to allow calling the sortable's native _intersectsWith
|
1593 |
this.instance.positionAbs = inst.positionAbs;
|
1594 |
this.instance.helperProportions = inst.helperProportions;
|
1595 |
this.instance.offset.click = inst.offset.click;
|
1596 |
+
|
1597 |
if(this.instance._intersectsWith(this.instance.containerCache)) {
|
1598 |
+
innermostIntersecting = true;
|
1599 |
+
$.each(inst.sortables, function () {
|
1600 |
+
this.instance.positionAbs = inst.positionAbs;
|
1601 |
+
this.instance.helperProportions = inst.helperProportions;
|
1602 |
+
this.instance.offset.click = inst.offset.click;
|
1603 |
+
if (this !== thisSortable &&
|
1604 |
+
this.instance._intersectsWith(this.instance.containerCache) &&
|
1605 |
+
$.contains(thisSortable.instance.element[0], this.instance.element[0])
|
1606 |
+
) {
|
1607 |
+
innermostIntersecting = false;
|
1608 |
+
}
|
1609 |
+
return innermostIntersecting;
|
1610 |
+
});
|
1611 |
+
}
|
1612 |
|
1613 |
+
|
1614 |
+
if(innermostIntersecting) {
|
1615 |
//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
|
1616 |
if(!this.instance.isOver) {
|
1617 |
|
1619 |
//Now we fake the start of dragging for the sortable instance,
|
1620 |
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
|
1621 |
//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)
|
1622 |
+
this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
|
1623 |
this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
|
1624 |
this.instance.options.helper = function() { return ui.helper[0]; };
|
1625 |
|
1642 |
}
|
1643 |
|
1644 |
//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
|
1645 |
+
if(this.instance.currentItem) {
|
1646 |
+
this.instance._mouseDrag(event);
|
1647 |
+
}
|
1648 |
|
1649 |
} else {
|
1650 |
|
1654 |
|
1655 |
this.instance.isOver = 0;
|
1656 |
this.instance.cancelHelperRemoval = true;
|
1657 |
+
|
1658 |
//Prevent reverting on this forced stop
|
1659 |
this.instance.options.revert = false;
|
1660 |
+
|
1661 |
// The out event needs to be triggered independently
|
1662 |
+
this.instance._trigger("out", event, this.instance._uiHash(this.instance));
|
1663 |
+
|
1664 |
this.instance._mouseStop(event, true);
|
1665 |
this.instance.options.helper = this.instance.options._helper;
|
1666 |
|
1667 |
//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
|
1668 |
this.instance.currentItem.remove();
|
1669 |
+
if(this.instance.placeholder) {
|
1670 |
+
this.instance.placeholder.remove();
|
1671 |
+
}
|
1672 |
|
1673 |
inst._trigger("fromSortable", event);
|
1674 |
inst.dropped = false; //draggable revert needs that
|
1675 |
}
|
1676 |
|
1677 |
+
}
|
1678 |
|
1679 |
});
|
1680 |
|
1682 |
});
|
1683 |
|
1684 |
$.ui.plugin.add("draggable", "cursor", {
|
1685 |
+
start: function() {
|
1686 |
+
var t = $("body"), o = $(this).data("ui-draggable").options;
|
1687 |
+
if (t.css("cursor")) {
|
1688 |
+
o._cursor = t.css("cursor");
|
1689 |
+
}
|
1690 |
t.css("cursor", o.cursor);
|
1691 |
},
|
1692 |
+
stop: function() {
|
1693 |
+
var o = $(this).data("ui-draggable").options;
|
1694 |
+
if (o._cursor) {
|
1695 |
+
$("body").css("cursor", o._cursor);
|
1696 |
+
}
|
1697 |
}
|
1698 |
});
|
1699 |
|
1700 |
$.ui.plugin.add("draggable", "opacity", {
|
1701 |
start: function(event, ui) {
|
1702 |
+
var t = $(ui.helper), o = $(this).data("ui-draggable").options;
|
1703 |
+
if(t.css("opacity")) {
|
1704 |
+
o._opacity = t.css("opacity");
|
1705 |
+
}
|
1706 |
+
t.css("opacity", o.opacity);
|
1707 |
},
|
1708 |
stop: function(event, ui) {
|
1709 |
+
var o = $(this).data("ui-draggable").options;
|
1710 |
+
if(o._opacity) {
|
1711 |
+
$(ui.helper).css("opacity", o._opacity);
|
1712 |
+
}
|
1713 |
}
|
1714 |
});
|
1715 |
|
1716 |
$.ui.plugin.add("draggable", "scroll", {
|
1717 |
+
start: function() {
|
1718 |
+
var i = $(this).data("ui-draggable");
|
1719 |
+
if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
|
1720 |
+
i.overflowOffset = i.scrollParent.offset();
|
1721 |
+
}
|
1722 |
},
|
1723 |
+
drag: function( event ) {
|
1724 |
|
1725 |
+
var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
|
1726 |
|
1727 |
+
if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
|
1728 |
|
1729 |
+
if(!o.axis || o.axis !== "x") {
|
1730 |
+
if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
|
1731 |
i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
|
1732 |
+
} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
|
1733 |
i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
|
1734 |
+
}
|
1735 |
}
|
1736 |
|
1737 |
+
if(!o.axis || o.axis !== "y") {
|
1738 |
+
if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
|
1739 |
i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
|
1740 |
+
} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
|
1741 |
i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
|
1742 |
+
}
|
1743 |
}
|
1744 |
|
1745 |
} else {
|
1746 |
|
1747 |
+
if(!o.axis || o.axis !== "x") {
|
1748 |
+
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
|
1749 |
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
1750 |
+
} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
|
1751 |
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
1752 |
+
}
|
1753 |
}
|
1754 |
|
1755 |
+
if(!o.axis || o.axis !== "y") {
|
1756 |
+
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
|
1757 |
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
1758 |
+
} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
|
1759 |
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
1760 |
+
}
|
1761 |
}
|
1762 |
|
1763 |
}
|
1764 |
|
1765 |
+
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
|
1766 |
$.ui.ddmanager.prepareOffsets(i, event);
|
1767 |
+
}
|
1768 |
|
1769 |
}
|
1770 |
});
|
1771 |
|
1772 |
$.ui.plugin.add("draggable", "snap", {
|
1773 |
+
start: function() {
|
1774 |
+
|
1775 |
+
var i = $(this).data("ui-draggable"),
|
1776 |
+
o = i.options;
|
1777 |
|
|
|
1778 |
i.snapElements = [];
|
1779 |
|
1780 |
+
$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
|
1781 |
+
var $t = $(this),
|
1782 |
+
$o = $t.offset();
|
1783 |
+
if(this !== i.element[0]) {
|
1784 |
+
i.snapElements.push({
|
1785 |
+
item: this,
|
1786 |
+
width: $t.outerWidth(), height: $t.outerHeight(),
|
1787 |
+
top: $o.top, left: $o.left
|
1788 |
+
});
|
1789 |
+
}
|
1790 |
});
|
1791 |
|
1792 |
},
|
1793 |
drag: function(event, ui) {
|
1794 |
|
1795 |
+
var ts, bs, ls, rs, l, r, t, b, i, first,
|
1796 |
+
inst = $(this).data("ui-draggable"),
|
1797 |
+
o = inst.options,
|
1798 |
+
d = o.snapTolerance,
|
1799 |
+
x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
|
1800 |
y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
|
1801 |
|
1802 |
+
for (i = inst.snapElements.length - 1; i >= 0; i--){
|
1803 |
|
1804 |
+
l = inst.snapElements[i].left;
|
1805 |
+
r = l + inst.snapElements[i].width;
|
1806 |
+
t = inst.snapElements[i].top;
|
1807 |
+
b = t + inst.snapElements[i].height;
|
1808 |
|
1809 |
//Yes, I know, this is insane ;)
|
1810 |
if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
|
1811 |
+
if(inst.snapElements[i].snapping) {
|
1812 |
+
(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
|
1813 |
+
}
|
1814 |
inst.snapElements[i].snapping = false;
|
1815 |
continue;
|
1816 |
}
|
1817 |
|
1818 |
+
if(o.snapMode !== "inner") {
|
1819 |
+
ts = Math.abs(t - y2) <= d;
|
1820 |
+
bs = Math.abs(b - y1) <= d;
|
1821 |
+
ls = Math.abs(l - x2) <= d;
|
1822 |
+
rs = Math.abs(r - x1) <= d;
|
1823 |
+
if(ts) {
|
1824 |
+
ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
|
1825 |
+
}
|
1826 |
+
if(bs) {
|
1827 |
+
ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
|
1828 |
+
}
|
1829 |
+
if(ls) {
|
1830 |
+
ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
|
1831 |
+
}
|
1832 |
+
if(rs) {
|
1833 |
+
ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
|
1834 |
+
}
|
1835 |
}
|
1836 |
|
1837 |
+
first = (ts || bs || ls || rs);
|
1838 |
|
1839 |
+
if(o.snapMode !== "outer") {
|
1840 |
+
ts = Math.abs(t - y1) <= d;
|
1841 |
+
bs = Math.abs(b - y2) <= d;
|
1842 |
+
ls = Math.abs(l - x1) <= d;
|
1843 |
+
rs = Math.abs(r - x2) <= d;
|
1844 |
+
if(ts) {
|
1845 |
+
ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
|
1846 |
+
}
|
1847 |
+
if(bs) {
|
1848 |
+
ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
|
1849 |
+
}
|
1850 |
+
if(ls) {
|
1851 |
+
ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
|
1852 |
+
}
|
1853 |
+
if(rs) {
|
1854 |
+
ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
|
1855 |
+
}
|
1856 |
}
|
1857 |
|
1858 |
+
if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
|
1859 |
(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
|
1860 |
+
}
|
1861 |
inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
|
1862 |
|
1863 |
+
}
|
1864 |
|
1865 |
}
|
1866 |
});
|
1867 |
|
1868 |
$.ui.plugin.add("draggable", "stack", {
|
1869 |
+
start: function() {
|
1870 |
+
var min,
|
1871 |
+
o = this.data("ui-draggable").options,
|
1872 |
+
group = $.makeArray($(o.stack)).sort(function(a,b) {
|
1873 |
+
return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
|
1874 |
+
});
|
1875 |
|
|
|
|
|
|
|
1876 |
if (!group.length) { return; }
|
1877 |
+
|
1878 |
+
min = parseInt($(group[0]).css("zIndex"), 10) || 0;
|
1879 |
$(group).each(function(i) {
|
1880 |
+
$(this).css("zIndex", min + i);
|
1881 |
});
|
1882 |
+
this.css("zIndex", (min + group.length));
|
|
|
|
|
1883 |
}
|
1884 |
});
|
1885 |
|
1886 |
$.ui.plugin.add("draggable", "zIndex", {
|
1887 |
start: function(event, ui) {
|
1888 |
+
var t = $(ui.helper), o = $(this).data("ui-draggable").options;
|
1889 |
+
if(t.css("zIndex")) {
|
1890 |
+
o._zIndex = t.css("zIndex");
|
1891 |
+
}
|
1892 |
+
t.css("zIndex", o.zIndex);
|
1893 |
},
|
1894 |
stop: function(event, ui) {
|
1895 |
+
var o = $(this).data("ui-draggable").options;
|
1896 |
+
if(o._zIndex) {
|
1897 |
+
$(ui.helper).css("zIndex", o._zIndex);
|
1898 |
+
}
|
1899 |
}
|
1900 |
});
|
1901 |
|
1902 |
})(jQuery);
|
1903 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1904 |
(function( $, undefined ) {
|
1905 |
|
1906 |
+
function isOverAxis( x, reference, size ) {
|
1907 |
+
return ( x > reference ) && ( x < ( reference + size ) );
|
1908 |
+
}
|
1909 |
+
|
1910 |
$.widget("ui.droppable", {
|
1911 |
+
version: "1.10.2",
|
1912 |
widgetEventPrefix: "drop",
|
1913 |
options: {
|
1914 |
+
accept: "*",
|
1915 |
activeClass: false,
|
1916 |
addClasses: true,
|
1917 |
greedy: false,
|
1918 |
hoverClass: false,
|
1919 |
+
scope: "default",
|
1920 |
+
tolerance: "intersect",
|
1921 |
+
|
1922 |
+
// callbacks
|
1923 |
+
activate: null,
|
1924 |
+
deactivate: null,
|
1925 |
+
drop: null,
|
1926 |
+
out: null,
|
1927 |
+
over: null
|
1928 |
},
|
1929 |
_create: function() {
|
1930 |
|
1931 |
+
var o = this.options,
|
1932 |
+
accept = o.accept;
|
1933 |
+
|
1934 |
+
this.isover = false;
|
1935 |
+
this.isout = true;
|
1936 |
|
1937 |
this.accept = $.isFunction(accept) ? accept : function(d) {
|
1938 |
return d.is(accept);
|
1949 |
|
1950 |
},
|
1951 |
|
1952 |
+
_destroy: function() {
|
1953 |
+
var i = 0,
|
1954 |
+
drop = $.ui.ddmanager.droppables[this.options.scope];
|
|
|
|
|
1955 |
|
1956 |
+
for ( ; i < drop.length; i++ ) {
|
1957 |
+
if ( drop[i] === this ) {
|
1958 |
+
drop.splice(i, 1);
|
1959 |
+
}
|
1960 |
+
}
|
1961 |
|
1962 |
+
this.element.removeClass("ui-droppable ui-droppable-disabled");
|
1963 |
},
|
1964 |
|
1965 |
_setOption: function(key, value) {
|
1966 |
|
1967 |
+
if(key === "accept") {
|
1968 |
this.accept = $.isFunction(value) ? value : function(d) {
|
1969 |
return d.is(value);
|
1970 |
};
|
1974 |
|
1975 |
_activate: function(event) {
|
1976 |
var draggable = $.ui.ddmanager.current;
|
1977 |
+
if(this.options.activeClass) {
|
1978 |
+
this.element.addClass(this.options.activeClass);
|
1979 |
+
}
|
1980 |
+
if(draggable){
|
1981 |
+
this._trigger("activate", event, this.ui(draggable));
|
1982 |
+
}
|
1983 |
},
|
1984 |
|
1985 |
_deactivate: function(event) {
|
1986 |
var draggable = $.ui.ddmanager.current;
|
1987 |
+
if(this.options.activeClass) {
|
1988 |
+
this.element.removeClass(this.options.activeClass);
|
1989 |
+
}
|
1990 |
+
if(draggable){
|
1991 |
+
this._trigger("deactivate", event, this.ui(draggable));
|
1992 |
+
}
|
1993 |
},
|
1994 |
|
1995 |
_over: function(event) {
|
1996 |
|
1997 |
var draggable = $.ui.ddmanager.current;
|
1998 |
+
|
1999 |
+
// Bail if draggable and droppable are same element
|
2000 |
+
if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
|
2001 |
+
return;
|
2002 |
+
}
|
2003 |
|
2004 |
if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
2005 |
+
if(this.options.hoverClass) {
|
2006 |
+
this.element.addClass(this.options.hoverClass);
|
2007 |
+
}
|
2008 |
+
this._trigger("over", event, this.ui(draggable));
|
2009 |
}
|
2010 |
|
2011 |
},
|
2013 |
_out: function(event) {
|
2014 |
|
2015 |
var draggable = $.ui.ddmanager.current;
|
2016 |
+
|
2017 |
+
// Bail if draggable and droppable are same element
|
2018 |
+
if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
|
2019 |
+
return;
|
2020 |
+
}
|
2021 |
|
2022 |
if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
2023 |
+
if(this.options.hoverClass) {
|
2024 |
+
this.element.removeClass(this.options.hoverClass);
|
2025 |
+
}
|
2026 |
+
this._trigger("out", event, this.ui(draggable));
|
2027 |
}
|
2028 |
|
2029 |
},
|
2030 |
|
2031 |
_drop: function(event,custom) {
|
2032 |
|
2033 |
+
var draggable = custom || $.ui.ddmanager.current,
|
2034 |
+
childrenIntersection = false;
|
2035 |
+
|
2036 |
+
// Bail if draggable and droppable are same element
|
2037 |
+
if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
|
2038 |
+
return false;
|
2039 |
+
}
|
2040 |
|
2041 |
+
this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
|
2042 |
+
var inst = $.data(this, "ui-droppable");
|
|
|
2043 |
if(
|
2044 |
+
inst.options.greedy &&
|
2045 |
+
!inst.options.disabled &&
|
2046 |
+
inst.options.scope === draggable.options.scope &&
|
2047 |
+
inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
|
2048 |
+
$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
|
2049 |
) { childrenIntersection = true; return false; }
|
2050 |
});
|
2051 |
+
if(childrenIntersection) {
|
2052 |
+
return false;
|
2053 |
+
}
|
2054 |
|
2055 |
if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
2056 |
+
if(this.options.activeClass) {
|
2057 |
+
this.element.removeClass(this.options.activeClass);
|
2058 |
+
}
|
2059 |
+
if(this.options.hoverClass) {
|
2060 |
+
this.element.removeClass(this.options.hoverClass);
|
2061 |
+
}
|
2062 |
+
this._trigger("drop", event, this.ui(draggable));
|
2063 |
return this.element;
|
2064 |
}
|
2065 |
|
2078 |
|
2079 |
});
|
2080 |
|
|
|
|
|
|
|
|
|
2081 |
$.ui.intersect = function(draggable, droppable, toleranceMode) {
|
2082 |
|
2083 |
+
if (!droppable.offset) {
|
2084 |
+
return false;
|
2085 |
+
}
|
2086 |
|
2087 |
+
var draggableLeft, draggableTop,
|
2088 |
+
x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
|
2089 |
+
y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
|
2090 |
+
l = droppable.offset.left, r = l + droppable.proportions.width,
|
2091 |
t = droppable.offset.top, b = t + droppable.proportions.height;
|
2092 |
|
2093 |
switch (toleranceMode) {
|
2094 |
+
case "fit":
|
2095 |
+
return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
|
2096 |
+
case "intersect":
|
2097 |
+
return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
|
2098 |
+
x2 - (draggable.helperProportions.width / 2) < r && // Left Half
|
2099 |
+
t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
|
2100 |
+
y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
|
2101 |
+
case "pointer":
|
2102 |
+
draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
|
2103 |
+
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
|
2104 |
+
return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
|
2105 |
+
case "touch":
|
|
|
|
|
|
|
|
|
|
|
2106 |
return (
|
2107 |
+
(y1 >= t && y1 <= b) || // Top edge touching
|
2108 |
+
(y2 >= t && y2 <= b) || // Bottom edge touching
|
2109 |
+
(y1 < t && y2 > b) // Surrounded vertically
|
2110 |
+
) && (
|
2111 |
+
(x1 >= l && x1 <= r) || // Left edge touching
|
2112 |
+
(x2 >= l && x2 <= r) || // Right edge touching
|
2113 |
+
(x1 < l && x2 > r) // Surrounded horizontally
|
2114 |
+
);
|
|
|
2115 |
default:
|
2116 |
return false;
|
|
|
2117 |
}
|
2118 |
|
2119 |
};
|
2123 |
*/
|
2124 |
$.ui.ddmanager = {
|
2125 |
current: null,
|
2126 |
+
droppables: { "default": [] },
|
2127 |
prepareOffsets: function(t, event) {
|
2128 |
|
2129 |
+
var i, j,
|
2130 |
+
m = $.ui.ddmanager.droppables[t.options.scope] || [],
|
2131 |
+
type = event ? event.type : null, // workaround for #2317
|
2132 |
+
list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
|
2133 |
+
|
2134 |
+
droppablesLoop: for (i = 0; i < m.length; i++) {
|
2135 |
|
2136 |
+
//No disabled and non-accepted
|
2137 |
+
if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
|
2138 |
+
continue;
|
2139 |
+
}
|
2140 |
+
|
2141 |
+
// Filter out elements in the current dragged item
|
2142 |
+
for (j=0; j < list.length; j++) {
|
2143 |
+
if(list[j] === m[i].element[0]) {
|
2144 |
+
m[i].proportions.height = 0;
|
2145 |
+
continue droppablesLoop;
|
2146 |
+
}
|
2147 |
+
}
|
2148 |
|
2149 |
+
m[i].visible = m[i].element.css("display") !== "none";
|
2150 |
+
if(!m[i].visible) {
|
2151 |
+
continue;
|
2152 |
+
}
|
2153 |
|
2154 |
+
//Activate the droppable if used directly from draggables
|
2155 |
+
if(type === "mousedown") {
|
2156 |
+
m[i]._activate.call(m[i], event);
|
2157 |
+
}
|
2158 |
|
2159 |
m[i].offset = m[i].element.offset();
|
2160 |
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
|
2165 |
drop: function(draggable, event) {
|
2166 |
|
2167 |
var dropped = false;
|
2168 |
+
// Create a copy of the droppables in case the list changes during the drop (#9116)
|
2169 |
+
$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
|
2170 |
|
2171 |
+
if(!this.options) {
|
2172 |
+
return;
|
2173 |
+
}
|
2174 |
+
if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
|
2175 |
dropped = this._drop.call(this, event) || dropped;
|
2176 |
+
}
|
2177 |
|
2178 |
if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
|
2179 |
+
this.isout = true;
|
2180 |
+
this.isover = false;
|
2181 |
this._deactivate.call(this, event);
|
2182 |
}
|
2183 |
|
2187 |
},
|
2188 |
dragStart: function( draggable, event ) {
|
2189 |
//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
|
2190 |
+
draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
|
2191 |
+
if( !draggable.options.refreshPositions ) {
|
2192 |
+
$.ui.ddmanager.prepareOffsets( draggable, event );
|
2193 |
+
}
|
2194 |
});
|
2195 |
},
|
2196 |
drag: function(draggable, event) {
|
2197 |
|
2198 |
//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
|
2199 |
+
if(draggable.options.refreshPositions) {
|
2200 |
+
$.ui.ddmanager.prepareOffsets(draggable, event);
|
2201 |
+
}
|
2202 |
|
2203 |
//Run through all droppables and check their positions based on specific tolerance options
|
2204 |
$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
|
2205 |
|
2206 |
+
if(this.options.disabled || this.greedyChild || !this.visible) {
|
2207 |
+
return;
|
2208 |
+
}
|
2209 |
|
2210 |
+
var parentInstance, scope, parent,
|
2211 |
+
intersects = $.ui.intersect(draggable, this, this.options.tolerance),
|
2212 |
+
c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
|
2213 |
+
if(!c) {
|
2214 |
+
return;
|
2215 |
+
}
|
2216 |
|
|
|
2217 |
if (this.options.greedy) {
|
2218 |
+
// find droppable parents with same scope
|
2219 |
+
scope = this.options.scope;
|
2220 |
+
parent = this.element.parents(":data(ui-droppable)").filter(function () {
|
2221 |
+
return $.data(this, "ui-droppable").options.scope === scope;
|
2222 |
+
});
|
2223 |
+
|
2224 |
if (parent.length) {
|
2225 |
+
parentInstance = $.data(parent[0], "ui-droppable");
|
2226 |
+
parentInstance.greedyChild = (c === "isover");
|
2227 |
}
|
2228 |
}
|
2229 |
|
2230 |
// we just moved into a greedy child
|
2231 |
+
if (parentInstance && c === "isover") {
|
2232 |
+
parentInstance.isover = false;
|
2233 |
+
parentInstance.isout = true;
|
2234 |
parentInstance._out.call(parentInstance, event);
|
2235 |
}
|
2236 |
|
2237 |
+
this[c] = true;
|
2238 |
+
this[c === "isout" ? "isover" : "isout"] = false;
|
2239 |
+
this[c === "isover" ? "_over" : "_out"].call(this, event);
|
2240 |
|
2241 |
// we just moved out of a greedy child
|
2242 |
+
if (parentInstance && c === "isout") {
|
2243 |
+
parentInstance.isout = false;
|
2244 |
+
parentInstance.isover = true;
|
2245 |
parentInstance._over.call(parentInstance, event);
|
2246 |
}
|
2247 |
});
|
2248 |
|
2249 |
},
|
2250 |
dragStop: function( draggable, event ) {
|
2251 |
+
draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
|
2252 |
//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
|
2253 |
+
if( !draggable.options.refreshPositions ) {
|
2254 |
+
$.ui.ddmanager.prepareOffsets( draggable, event );
|
2255 |
+
}
|
2256 |
}
|
2257 |
};
|
2258 |
|
2259 |
})(jQuery);
|
2260 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2261 |
(function( $, undefined ) {
|
2262 |
|
2263 |
+
function num(v) {
|
2264 |
+
return parseInt(v, 10) || 0;
|
2265 |
+
}
|
2266 |
+
|
2267 |
+
function isNumber(value) {
|
2268 |
+
return !isNaN(parseInt(value, 10));
|
2269 |
+
}
|
2270 |
+
|
2271 |
$.widget("ui.resizable", $.ui.mouse, {
|
2272 |
+
version: "1.10.2",
|
2273 |
widgetEventPrefix: "resize",
|
2274 |
options: {
|
2275 |
alsoResize: false,
|
2287 |
maxWidth: null,
|
2288 |
minHeight: 10,
|
2289 |
minWidth: 10,
|
2290 |
+
// See #7960
|
2291 |
+
zIndex: 90,
|
2292 |
+
|
2293 |
+
// callbacks
|
2294 |
+
resize: null,
|
2295 |
+
start: null,
|
2296 |
+
stop: null
|
2297 |
},
|
2298 |
_create: function() {
|
2299 |
|
2300 |
+
var n, i, handle, axis, hname,
|
2301 |
+
that = this,
|
2302 |
+
o = this.options;
|
2303 |
this.element.addClass("ui-resizable");
|
2304 |
|
2305 |
$.extend(this, {
|
2307 |
aspectRatio: o.aspectRatio,
|
2308 |
originalElement: this.element,
|
2309 |
_proportionallyResizeElements: [],
|
2310 |
+
_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
|
2311 |
});
|
2312 |
|
2313 |
//Wrap the element if it cannot hold child nodes
|
2314 |
if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
|
2315 |
|
|
|
|
|
|
|
|
|
2316 |
//Create a wrapper element and set the wrapper to the new current internal element
|
2317 |
this.element.wrap(
|
2318 |
+
$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
|
2319 |
+
position: this.element.css("position"),
|
2320 |
width: this.element.outerWidth(),
|
2321 |
height: this.element.outerHeight(),
|
2322 |
+
top: this.element.css("top"),
|
2323 |
+
left: this.element.css("left")
|
2324 |
})
|
2325 |
);
|
2326 |
|
2327 |
//Overwrite the original this.element
|
2328 |
this.element = this.element.parent().data(
|
2329 |
+
"ui-resizable", this.element.data("ui-resizable")
|
2330 |
);
|
2331 |
|
2332 |
this.elementIsWrapper = true;
|
2336 |
this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
|
2337 |
|
2338 |
//Prevent Safari textarea resize
|
2339 |
+
this.originalResizeStyle = this.originalElement.css("resize");
|
2340 |
+
this.originalElement.css("resize", "none");
|
2341 |
|
2342 |
//Push the actual element to our proportionallyResize internal array
|
2343 |
+
this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
|
2344 |
|
2345 |
// avoid IE jump (hard set the margin)
|
2346 |
+
this.originalElement.css({ margin: this.originalElement.css("margin") });
|
2347 |
|
2348 |
// fix handlers offset
|
2349 |
this._proportionallyResize();
|
2350 |
|
2351 |
}
|
2352 |
|
2353 |
+
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" });
|
2354 |
+
if(this.handles.constructor === String) {
|
2355 |
+
|
2356 |
+
if ( this.handles === "all") {
|
2357 |
+
this.handles = "n,e,s,w,se,sw,ne,nw";
|
2358 |
+
}
|
2359 |
|
2360 |
+
n = this.handles.split(",");
|
2361 |
+
this.handles = {};
|
2362 |
|
2363 |
+
for(i = 0; i < n.length; i++) {
|
2364 |
|
2365 |
+
handle = $.trim(n[i]);
|
2366 |
+
hname = "ui-resizable-"+handle;
|
2367 |
+
axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
|
2368 |
|
2369 |
+
// Apply zIndex to all handles - see #7960
|
2370 |
+
axis.css({ zIndex: o.zIndex });
|
|
|
2371 |
|
2372 |
//TODO : What's going on here?
|
2373 |
+
if ("se" === handle) {
|
2374 |
+
axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
|
2375 |
+
}
|
2376 |
|
2377 |
//Insert into internal handles object and append to element
|
2378 |
+
this.handles[handle] = ".ui-resizable-"+handle;
|
2379 |
this.element.append(axis);
|
2380 |
}
|
2381 |
|
2383 |
|
2384 |
this._renderAxis = function(target) {
|
2385 |
|
2386 |
+
var i, axis, padPos, padWrapper;
|
2387 |
+
|
2388 |
target = target || this.element;
|
2389 |
|
2390 |
+
for(i in this.handles) {
|
2391 |
|
2392 |
+
if(this.handles[i].constructor === String) {
|
2393 |
this.handles[i] = $(this.handles[i], this.element).show();
|
2394 |
+
}
|
2395 |
|
2396 |
//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
|
2397 |
if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
|
2398 |
|
2399 |
+
axis = $(this.handles[i], this.element);
|
2400 |
|
2401 |
//Checking the correct pad and border
|
2402 |
padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
|
2403 |
|
2404 |
//The padding type i have to apply...
|
2405 |
+
padPos = [ "padding",
|
2406 |
+
/ne|nw|n/.test(i) ? "Top" :
|
2407 |
+
/se|sw|s/.test(i) ? "Bottom" :
|
2408 |
+
/^e$/.test(i) ? "Right" : "Left" ].join("");
|
2409 |
|
2410 |
target.css(padPos, padWrapper);
|
2411 |
|
2414 |
}
|
2415 |
|
2416 |
//TODO: What's that good for? There's not anything to be executed left
|
2417 |
+
if(!$(this.handles[i]).length) {
|
2418 |
continue;
|
2419 |
+
}
|
2420 |
}
|
2421 |
};
|
2422 |
|
2423 |
//TODO: make renderAxis a prototype function
|
2424 |
this._renderAxis(this.element);
|
2425 |
|
2426 |
+
this._handles = $(".ui-resizable-handle", this.element)
|
2427 |
.disableSelection();
|
2428 |
|
2429 |
//Matching axis name
|
2430 |
this._handles.mouseover(function() {
|
2431 |
+
if (!that.resizing) {
|
2432 |
+
if (this.className) {
|
2433 |
+
axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
|
2434 |
+
}
|
2435 |
//Axis, default = se
|
2436 |
+
that.axis = axis && axis[1] ? axis[1] : "se";
|
2437 |
}
|
2438 |
});
|
2439 |
|
2442 |
this._handles.hide();
|
2443 |
$(this.element)
|
2444 |
.addClass("ui-resizable-autohide")
|
2445 |
+
.mouseenter(function() {
|
2446 |
+
if (o.disabled) {
|
2447 |
+
return;
|
2448 |
+
}
|
2449 |
$(this).removeClass("ui-resizable-autohide");
|
2450 |
+
that._handles.show();
|
2451 |
+
})
|
2452 |
+
.mouseleave(function(){
|
2453 |
+
if (o.disabled) {
|
2454 |
+
return;
|
2455 |
+
}
|
2456 |
+
if (!that.resizing) {
|
2457 |
$(this).addClass("ui-resizable-autohide");
|
2458 |
+
that._handles.hide();
|
2459 |
}
|
2460 |
});
|
2461 |
}
|
2465 |
|
2466 |
},
|
2467 |
|
2468 |
+
_destroy: function() {
|
2469 |
|
2470 |
this._mouseDestroy();
|
2471 |
|
2472 |
+
var wrapper,
|
2473 |
+
_destroy = function(exp) {
|
2474 |
+
$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
|
2475 |
+
.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
|
2476 |
+
};
|
2477 |
|
2478 |
//TODO: Unwrap at same DOM position
|
2479 |
if (this.elementIsWrapper) {
|
2480 |
_destroy(this.element);
|
2481 |
+
wrapper = this.element;
|
2482 |
+
this.originalElement.css({
|
2483 |
+
position: wrapper.css("position"),
|
2484 |
+
width: wrapper.outerWidth(),
|
2485 |
+
height: wrapper.outerHeight(),
|
2486 |
+
top: wrapper.css("top"),
|
2487 |
+
left: wrapper.css("left")
|
2488 |
+
}).insertAfter( wrapper );
|
2489 |
+
wrapper.remove();
|
2490 |
+
}
|
2491 |
+
|
2492 |
+
this.originalElement.css("resize", this.originalResizeStyle);
|
|
|
2493 |
_destroy(this.originalElement);
|
2494 |
|
2495 |
return this;
|
2496 |
},
|
2497 |
|
2498 |
_mouseCapture: function(event) {
|
2499 |
+
var i, handle,
|
2500 |
+
capture = false;
|
2501 |
+
|
2502 |
+
for (i in this.handles) {
|
2503 |
+
handle = $(this.handles[i])[0];
|
2504 |
+
if (handle === event.target || $.contains(handle, event.target)) {
|
2505 |
+
capture = true;
|
2506 |
}
|
2507 |
}
|
2508 |
|
2509 |
+
return !this.options.disabled && capture;
|
2510 |
},
|
2511 |
|
2512 |
_mouseStart: function(event) {
|
2513 |
|
2514 |
+
var curleft, curtop, cursor,
|
2515 |
+
o = this.options,
|
2516 |
+
iniPos = this.element.position(),
|
2517 |
+
el = this.element;
|
2518 |
|
2519 |
this.resizing = true;
|
|
|
2520 |
|
2521 |
// bugfix for http://dev.jquery.com/ticket/1749
|
2522 |
+
if ( (/absolute/).test( el.css("position") ) ) {
|
2523 |
+
el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
|
2524 |
+
} else if (el.is(".ui-draggable")) {
|
2525 |
+
el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
|
2526 |
}
|
2527 |
|
|
|
|
|
|
|
|
|
2528 |
this._renderProxy();
|
2529 |
|
2530 |
+
curleft = num(this.helper.css("left"));
|
2531 |
+
curtop = num(this.helper.css("top"));
|
2532 |
|
2533 |
if (o.containment) {
|
2534 |
curleft += $(o.containment).scrollLeft() || 0;
|
2545 |
this.originalMousePosition = { left: event.pageX, top: event.pageY };
|
2546 |
|
2547 |
//Aspect Ratio
|
2548 |
+
this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
|
2549 |
|
2550 |
+
cursor = $(".ui-resizable-" + this.axis).css("cursor");
|
2551 |
+
$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
|
2552 |
|
2553 |
el.addClass("ui-resizable-resizing");
|
2554 |
this._propagate("start", event);
|
2558 |
_mouseDrag: function(event) {
|
2559 |
|
2560 |
//Increase performance, avoid regex
|
2561 |
+
var data,
|
2562 |
+
el = this.helper, props = {},
|
2563 |
+
smp = this.originalMousePosition,
|
2564 |
+
a = this.axis,
|
2565 |
+
prevTop = this.position.top,
|
2566 |
+
prevLeft = this.position.left,
|
2567 |
+
prevWidth = this.size.width,
|
2568 |
+
prevHeight = this.size.height,
|
2569 |
+
dx = (event.pageX-smp.left)||0,
|
2570 |
+
dy = (event.pageY-smp.top)||0,
|
2571 |
+
trigger = this._change[a];
|
2572 |
+
|
2573 |
+
if (!trigger) {
|
2574 |
+
return false;
|
2575 |
+
}
|
2576 |
|
2577 |
// Calculate the attrs that will be change
|
2578 |
+
data = trigger.apply(this, [event, dx, dy]);
|
2579 |
|
2580 |
// Put this in the mouseDrag handler since the user can start pressing shift while resizing
|
2581 |
this._updateVirtualBoundaries(event.shiftKey);
|
2582 |
+
if (this._aspectRatio || event.shiftKey) {
|
2583 |
data = this._updateRatio(data, event);
|
2584 |
+
}
|
2585 |
|
2586 |
data = this._respectSize(data, event);
|
2587 |
|
2588 |
+
this._updateCache(data);
|
2589 |
+
|
2590 |
// plugins callbacks need to be called first
|
2591 |
this._propagate("resize", event);
|
2592 |
|
2593 |
+
if (this.position.top !== prevTop) {
|
2594 |
+
props.top = this.position.top + "px";
|
2595 |
+
}
|
2596 |
+
if (this.position.left !== prevLeft) {
|
2597 |
+
props.left = this.position.left + "px";
|
2598 |
+
}
|
2599 |
+
if (this.size.width !== prevWidth) {
|
2600 |
+
props.width = this.size.width + "px";
|
2601 |
+
}
|
2602 |
+
if (this.size.height !== prevHeight) {
|
2603 |
+
props.height = this.size.height + "px";
|
2604 |
+
}
|
2605 |
+
el.css(props);
|
2606 |
|
2607 |
+
if (!this._helper && this._proportionallyResizeElements.length) {
|
2608 |
this._proportionallyResize();
|
2609 |
+
}
|
2610 |
|
2611 |
+
// Call the user callback if the element was resized
|
2612 |
+
if ( ! $.isEmptyObject(props) ) {
|
2613 |
+
this._trigger("resize", event, this.ui());
|
2614 |
+
}
|
2615 |
|
2616 |
return false;
|
2617 |
},
|
2619 |
_mouseStop: function(event) {
|
2620 |
|
2621 |
this.resizing = false;
|
2622 |
+
var pr, ista, soffseth, soffsetw, s, left, top,
|
2623 |
+
o = this.options, that = this;
|
2624 |
|
2625 |
if(this._helper) {
|
|
|
|
|
|
|
2626 |
|
2627 |
+
pr = this._proportionallyResizeElements;
|
2628 |
+
ista = pr.length && (/textarea/i).test(pr[0].nodeName);
|
2629 |
+
soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
|
2630 |
+
soffsetw = ista ? 0 : that.sizeDiff.width;
|
2631 |
+
|
2632 |
+
s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) };
|
2633 |
+
left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
|
2634 |
+
top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
|
2635 |
|
2636 |
+
if (!o.animate) {
|
2637 |
this.element.css($.extend(s, { top: top, left: left }));
|
2638 |
+
}
|
2639 |
|
2640 |
+
that.helper.height(that.size.height);
|
2641 |
+
that.helper.width(that.size.width);
|
2642 |
|
2643 |
+
if (this._helper && !o.animate) {
|
2644 |
+
this._proportionallyResize();
|
2645 |
+
}
|
2646 |
}
|
2647 |
|
2648 |
+
$("body").css("cursor", "auto");
|
2649 |
|
2650 |
this.element.removeClass("ui-resizable-resizing");
|
2651 |
|
2652 |
this._propagate("stop", event);
|
2653 |
|
2654 |
+
if (this._helper) {
|
2655 |
+
this.helper.remove();
|
2656 |
+
}
|
2657 |
+
|
2658 |
return false;
|
2659 |
|
2660 |
},
|
2661 |
|
2662 |
+
_updateVirtualBoundaries: function(forceAspectRatio) {
|
2663 |
+
var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
|
2664 |
+
o = this.options;
|
2665 |
|
2666 |
+
b = {
|
2667 |
+
minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
|
2668 |
+
maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
|
2669 |
+
minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
|
2670 |
+
maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
|
2671 |
+
};
|
2672 |
|
2673 |
+
if(this._aspectRatio || forceAspectRatio) {
|
2674 |
+
// We want to create an enclosing box whose aspect ration is the requested one
|
2675 |
+
// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
|
2676 |
+
pMinWidth = b.minHeight * this.aspectRatio;
|
2677 |
+
pMinHeight = b.minWidth / this.aspectRatio;
|
2678 |
+
pMaxWidth = b.maxHeight * this.aspectRatio;
|
2679 |
+
pMaxHeight = b.maxWidth / this.aspectRatio;
|
2680 |
|
2681 |
+
if(pMinWidth > b.minWidth) {
|
2682 |
+
b.minWidth = pMinWidth;
|
2683 |
+
}
|
2684 |
+
if(pMinHeight > b.minHeight) {
|
2685 |
+
b.minHeight = pMinHeight;
|
2686 |
+
}
|
2687 |
+
if(pMaxWidth < b.maxWidth) {
|
2688 |
+
b.maxWidth = pMaxWidth;
|
2689 |
+
}
|
2690 |
+
if(pMaxHeight < b.maxHeight) {
|
2691 |
+
b.maxHeight = pMaxHeight;
|
2692 |
+
}
|
2693 |
+
}
|
2694 |
+
this._vBoundaries = b;
|
2695 |
+
},
|
2696 |
|
2697 |
_updateCache: function(data) {
|
|
|
2698 |
this.offset = this.helper.offset();
|
2699 |
+
if (isNumber(data.left)) {
|
2700 |
+
this.position.left = data.left;
|
2701 |
+
}
|
2702 |
+
if (isNumber(data.top)) {
|
2703 |
+
this.position.top = data.top;
|
2704 |
+
}
|
2705 |
+
if (isNumber(data.height)) {
|
2706 |
+
this.size.height = data.height;
|
2707 |
+
}
|
2708 |
+
if (isNumber(data.width)) {
|
2709 |
+
this.size.width = data.width;
|
2710 |
+
}
|
2711 |
},
|
2712 |
|
2713 |
+
_updateRatio: function( data ) {
|
2714 |
|
2715 |
+
var cpos = this.position,
|
2716 |
+
csize = this.size,
|
2717 |
+
a = this.axis;
|
2718 |
|
2719 |
+
if (isNumber(data.height)) {
|
2720 |
+
data.width = (data.height * this.aspectRatio);
|
2721 |
+
} else if (isNumber(data.width)) {
|
2722 |
+
data.height = (data.width / this.aspectRatio);
|
2723 |
+
}
|
2724 |
|
2725 |
+
if (a === "sw") {
|
2726 |
data.left = cpos.left + (csize.width - data.width);
|
2727 |
data.top = null;
|
2728 |
}
|
2729 |
+
if (a === "nw") {
|
2730 |
data.top = cpos.top + (csize.height - data.height);
|
2731 |
data.left = cpos.left + (csize.width - data.width);
|
2732 |
}
|
2734 |
return data;
|
2735 |
},
|
2736 |
|
2737 |
+
_respectSize: function( data ) {
|
2738 |
|
2739 |
+
var o = this._vBoundaries,
|
2740 |
+
a = this.axis,
|
2741 |
+
ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
|
2742 |
+
isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
|
2743 |
+
dw = this.originalPosition.left + this.originalSize.width,
|
2744 |
+
dh = this.position.top + this.size.height,
|
2745 |
+
cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
|
2746 |
+
if (isminw) {
|
2747 |
+
data.width = o.minWidth;
|
2748 |
+
}
|
2749 |
+
if (isminh) {
|
2750 |
+
data.height = o.minHeight;
|
2751 |
+
}
|
2752 |
+
if (ismaxw) {
|
2753 |
+
data.width = o.maxWidth;
|
2754 |
+
}
|
2755 |
+
if (ismaxh) {
|
2756 |
+
data.height = o.maxHeight;
|
2757 |
+
}
|
2758 |
|
2759 |
+
if (isminw && cw) {
|
2760 |
+
data.left = dw - o.minWidth;
|
2761 |
+
}
|
2762 |
+
if (ismaxw && cw) {
|
2763 |
+
data.left = dw - o.maxWidth;
|
2764 |
+
}
|
2765 |
+
if (isminh && ch) {
|
2766 |
+
data.top = dh - o.minHeight;
|
2767 |
+
}
|
2768 |
+
if (ismaxh && ch) {
|
2769 |
+
data.top = dh - o.maxHeight;
|
2770 |
+
}
|
2771 |
|
2772 |
// fixing jump error on top/left - bug #2330
|
2773 |
+
if (!data.width && !data.height && !data.left && data.top) {
|
2774 |
+
data.top = null;
|
2775 |
+
} else if (!data.width && !data.height && !data.top && data.left) {
|
2776 |
+
data.left = null;
|
2777 |
+
}
|
2778 |
|
2779 |
return data;
|
2780 |
},
|
2781 |
|
2782 |
_proportionallyResize: function() {
|
2783 |
|
2784 |
+
if (!this._proportionallyResizeElements.length) {
|
2785 |
+
return;
|
2786 |
+
}
|
2787 |
+
|
2788 |
+
var i, j, borders, paddings, prel,
|
2789 |
+
element = this.helper || this.element;
|
2790 |
|
2791 |
+
for ( i=0; i < this._proportionallyResizeElements.length; i++) {
|
2792 |
|
2793 |
+
prel = this._proportionallyResizeElements[i];
|
2794 |
|
2795 |
if (!this.borderDif) {
|
2796 |
+
this.borderDif = [];
|
2797 |
+
borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
|
2798 |
+
paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
|
2799 |
|
2800 |
+
for ( j = 0; j < borders.length; j++ ) {
|
2801 |
+
this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
|
2802 |
+
}
|
|
|
2803 |
}
|
2804 |
|
|
|
|
|
|
|
2805 |
prel.css({
|
2806 |
height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
|
2807 |
width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
|
2808 |
});
|
2809 |
|
2810 |
+
}
|
2811 |
|
2812 |
},
|
2813 |
|
2818 |
|
2819 |
if(this._helper) {
|
2820 |
|
2821 |
+
this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
|
|
|
|
|
|
|
|
|
2822 |
|
2823 |
this.helper.addClass(this._helper).css({
|
2824 |
+
width: this.element.outerWidth() - 1,
|
2825 |
+
height: this.element.outerHeight() - 1,
|
2826 |
+
position: "absolute",
|
2827 |
+
left: this.elementOffset.left +"px",
|
2828 |
+
top: this.elementOffset.top +"px",
|
2829 |
zIndex: ++o.zIndex //TODO: Don't modify option
|
2830 |
});
|
2831 |
|
2840 |
},
|
2841 |
|
2842 |
_change: {
|
2843 |
+
e: function(event, dx) {
|
2844 |
return { width: this.originalSize.width + dx };
|
2845 |
},
|
2846 |
+
w: function(event, dx) {
|
2847 |
+
var cs = this.originalSize, sp = this.originalPosition;
|
2848 |
return { left: sp.left + dx, width: cs.width - dx };
|
2849 |
},
|
2850 |
n: function(event, dx, dy) {
|
2851 |
+
var cs = this.originalSize, sp = this.originalPosition;
|
2852 |
return { top: sp.top + dy, height: cs.height - dy };
|
2853 |
},
|
2854 |
s: function(event, dx, dy) {
|
2870 |
|
2871 |
_propagate: function(n, event) {
|
2872 |
$.ui.plugin.call(this, n, [event, this.ui()]);
|
2873 |
+
(n !== "resize" && this._trigger(n, event, this.ui()));
|
2874 |
},
|
2875 |
|
2876 |
plugins: {},
|
2889 |
|
2890 |
});
|
2891 |
|
|
|
|
|
|
|
|
|
2892 |
/*
|
2893 |
* Resizable Extensions
|
2894 |
*/
|
2895 |
|
2896 |
+
$.ui.plugin.add("resizable", "animate", {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2897 |
|
2898 |
+
stop: function( event ) {
|
2899 |
+
var that = $(this).data("ui-resizable"),
|
2900 |
+
o = that.options,
|
2901 |
+
pr = that._proportionallyResizeElements,
|
2902 |
+
ista = pr.length && (/textarea/i).test(pr[0].nodeName),
|
2903 |
+
soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
|
2904 |
+
soffsetw = ista ? 0 : that.sizeDiff.width,
|
2905 |
+
style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
|
2906 |
+
left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
|
2907 |
+
top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
|
2908 |
+
|
2909 |
+
that.element.animate(
|
2910 |
+
$.extend(style, top && left ? { top: top, left: left } : {}), {
|
2911 |
+
duration: o.animateDuration,
|
2912 |
+
easing: o.animateEasing,
|
2913 |
+
step: function() {
|
2914 |
|
2915 |
+
var data = {
|
2916 |
+
width: parseInt(that.element.css("width"), 10),
|
2917 |
+
height: parseInt(that.element.css("height"), 10),
|
2918 |
+
top: parseInt(that.element.css("top"), 10),
|
2919 |
+
left: parseInt(that.element.css("left"), 10)
|
2920 |
+
};
|
2921 |
|
2922 |
+
if (pr && pr.length) {
|
2923 |
+
$(pr[0]).css({ width: data.width, height: data.height });
|
2924 |
+
}
|
|
|
2925 |
|
2926 |
+
// propagating resize, and updating values for each animation step
|
2927 |
+
that._updateCache(data);
|
2928 |
+
that._propagate("resize", event);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2929 |
|
2930 |
}
|
2931 |
}
|
2936 |
|
2937 |
$.ui.plugin.add("resizable", "containment", {
|
2938 |
|
2939 |
+
start: function() {
|
2940 |
+
var element, p, co, ch, cw, width, height,
|
2941 |
+
that = $(this).data("ui-resizable"),
|
2942 |
+
o = that.options,
|
2943 |
+
el = that.element,
|
2944 |
+
oc = o.containment,
|
2945 |
+
ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
|
2946 |
+
|
2947 |
+
if (!ce) {
|
2948 |
+
return;
|
2949 |
+
}
|
2950 |
|
2951 |
+
that.containerElement = $(ce);
|
2952 |
|
2953 |
+
if (/document/.test(oc) || oc === document) {
|
2954 |
+
that.containerOffset = { left: 0, top: 0 };
|
2955 |
+
that.containerPosition = { left: 0, top: 0 };
|
2956 |
|
2957 |
+
that.parentData = {
|
2958 |
element: $(document), left: 0, top: 0,
|
2959 |
width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
|
2960 |
};
|
2962 |
|
2963 |
// i'm a node, so compute top, left, right, bottom
|
2964 |
else {
|
2965 |
+
element = $(ce);
|
2966 |
+
p = [];
|
2967 |
$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
|
2968 |
|
2969 |
+
that.containerOffset = element.offset();
|
2970 |
+
that.containerPosition = element.position();
|
2971 |
+
that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
|
2972 |
|
2973 |
+
co = that.containerOffset;
|
2974 |
+
ch = that.containerSize.height;
|
2975 |
+
cw = that.containerSize.width;
|
2976 |
+
width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
|
2977 |
+
height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
|
2978 |
|
2979 |
+
that.parentData = {
|
2980 |
element: ce, left: co.left, top: co.top, width: width, height: height
|
2981 |
};
|
2982 |
}
|
2983 |
},
|
2984 |
|
2985 |
+
resize: function( event ) {
|
2986 |
+
var woset, hoset, isParent, isOffsetRelative,
|
2987 |
+
that = $(this).data("ui-resizable"),
|
2988 |
+
o = that.options,
|
2989 |
+
co = that.containerOffset, cp = that.position,
|
2990 |
+
pRatio = that._aspectRatio || event.shiftKey,
|
2991 |
+
cop = { top:0, left:0 }, ce = that.containerElement;
|
2992 |
|
2993 |
+
if (ce[0] !== document && (/static/).test(ce.css("position"))) {
|
2994 |
+
cop = co;
|
2995 |
+
}
|
2996 |
|
2997 |
+
if (cp.left < (that._helper ? co.left : 0)) {
|
2998 |
+
that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
|
2999 |
+
if (pRatio) {
|
3000 |
+
that.size.height = that.size.width / that.aspectRatio;
|
3001 |
+
}
|
3002 |
+
that.position.left = o.helper ? co.left : 0;
|
3003 |
}
|
3004 |
|
3005 |
+
if (cp.top < (that._helper ? co.top : 0)) {
|
3006 |
+
that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
|
3007 |
+
if (pRatio) {
|
3008 |
+
that.size.width = that.size.height * that.aspectRatio;
|
3009 |
+
}
|
3010 |
+
that.position.top = that._helper ? co.top : 0;
|
3011 |
}
|
3012 |
|
3013 |
+
that.offset.left = that.parentData.left+that.position.left;
|
3014 |
+
that.offset.top = that.parentData.top+that.position.top;
|
3015 |
|
3016 |
+
woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
|
3017 |
+
hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
|
3018 |
|
3019 |
+
isParent = that.containerElement.get(0) === that.element.parent().get(0);
|
3020 |
+
isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
|
3021 |
|
3022 |
+
if(isParent && isOffsetRelative) {
|
3023 |
+
woset -= that.parentData.left;
|
3024 |
+
}
|
3025 |
|
3026 |
+
if (woset + that.size.width >= that.parentData.width) {
|
3027 |
+
that.size.width = that.parentData.width - woset;
|
3028 |
+
if (pRatio) {
|
3029 |
+
that.size.height = that.size.width / that.aspectRatio;
|
3030 |
+
}
|
3031 |
}
|
3032 |
|
3033 |
+
if (hoset + that.size.height >= that.parentData.height) {
|
3034 |
+
that.size.height = that.parentData.height - hoset;
|
3035 |
+
if (pRatio) {
|
3036 |
+
that.size.width = that.size.height * that.aspectRatio;
|
3037 |
+
}
|
3038 |
}
|
3039 |
},
|
3040 |
|
3041 |
+
stop: function(){
|
3042 |
+
var that = $(this).data("ui-resizable"),
|
3043 |
+
o = that.options,
|
3044 |
+
co = that.containerOffset,
|
3045 |
+
cop = that.containerPosition,
|
3046 |
+
ce = that.containerElement,
|
3047 |
+
helper = $(that.helper),
|
3048 |
+
ho = helper.offset(),
|
3049 |
+
w = helper.outerWidth() - that.sizeDiff.width,
|
3050 |
+
h = helper.outerHeight() - that.sizeDiff.height;
|
3051 |
|
3052 |
+
if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
|
3053 |
$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
|
3054 |
+
}
|
3055 |
|
3056 |
+
if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
|
3057 |
$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
|
3058 |
+
}
|
3059 |
+
|
3060 |
+
}
|
3061 |
+
});
|
3062 |
+
|
3063 |
+
$.ui.plugin.add("resizable", "alsoResize", {
|
3064 |
+
|
3065 |
+
start: function () {
|
3066 |
+
var that = $(this).data("ui-resizable"),
|
3067 |
+
o = that.options,
|
3068 |
+
_store = function (exp) {
|
3069 |
+
$(exp).each(function() {
|
3070 |
+
var el = $(this);
|
3071 |
+
el.data("ui-resizable-alsoresize", {
|
3072 |
+
width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
|
3073 |
+
left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
|
3074 |
+
});
|
3075 |
+
});
|
3076 |
+
};
|
3077 |
+
|
3078 |
+
if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
|
3079 |
+
if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
|
3080 |
+
else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
|
3081 |
+
}else{
|
3082 |
+
_store(o.alsoResize);
|
3083 |
+
}
|
3084 |
+
},
|
3085 |
+
|
3086 |
+
resize: function (event, ui) {
|
3087 |
+
var that = $(this).data("ui-resizable"),
|
3088 |
+
o = that.options,
|
3089 |
+
os = that.originalSize,
|
3090 |
+
op = that.originalPosition,
|
3091 |
+
delta = {
|
3092 |
+
height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
|
3093 |
+
top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
|
3094 |
+
},
|
3095 |
+
|
3096 |
+
_alsoResize = function (exp, c) {
|
3097 |
+
$(exp).each(function() {
|
3098 |
+
var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
|
3099 |
+
css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
|
3100 |
+
|
3101 |
+
$.each(css, function (i, prop) {
|
3102 |
+
var sum = (start[prop]||0) + (delta[prop]||0);
|
3103 |
+
if (sum && sum >= 0) {
|
3104 |
+
style[prop] = sum || null;
|
3105 |
+
}
|
3106 |
+
});
|
3107 |
+
|
3108 |
+
el.css(style);
|
3109 |
+
});
|
3110 |
+
};
|
3111 |
|
3112 |
+
if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
|
3113 |
+
$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
|
3114 |
+
}else{
|
3115 |
+
_alsoResize(o.alsoResize);
|
3116 |
+
}
|
3117 |
+
},
|
3118 |
+
|
3119 |
+
stop: function () {
|
3120 |
+
$(this).removeData("resizable-alsoresize");
|
3121 |
}
|
3122 |
});
|
3123 |
|
3124 |
$.ui.plugin.add("resizable", "ghost", {
|
3125 |
|
3126 |
+
start: function() {
|
3127 |
|
3128 |
+
var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
|
3129 |
|
3130 |
+
that.ghost = that.originalElement.clone();
|
3131 |
+
that.ghost
|
3132 |
+
.css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
|
3133 |
+
.addClass("ui-resizable-ghost")
|
3134 |
+
.addClass(typeof o.ghost === "string" ? o.ghost : "");
|
3135 |
|
3136 |
+
that.ghost.appendTo(that.helper);
|
3137 |
|
3138 |
},
|
3139 |
|
3140 |
+
resize: function(){
|
3141 |
+
var that = $(this).data("ui-resizable");
|
3142 |
+
if (that.ghost) {
|
3143 |
+
that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
|
3144 |
+
}
|
3145 |
},
|
3146 |
|
3147 |
+
stop: function() {
|
3148 |
+
var that = $(this).data("ui-resizable");
|
3149 |
+
if (that.ghost && that.helper) {
|
3150 |
+
that.helper.get(0).removeChild(that.ghost.get(0));
|
3151 |
+
}
|
3152 |
}
|
3153 |
|
3154 |
});
|
3155 |
|
3156 |
$.ui.plugin.add("resizable", "grid", {
|
3157 |
|
3158 |
+
resize: function() {
|
3159 |
+
var that = $(this).data("ui-resizable"),
|
3160 |
+
o = that.options,
|
3161 |
+
cs = that.size,
|
3162 |
+
os = that.originalSize,
|
3163 |
+
op = that.originalPosition,
|
3164 |
+
a = that.axis,
|
3165 |
+
grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
|
3166 |
+
gridX = (grid[0]||1),
|
3167 |
+
gridY = (grid[1]||1),
|
3168 |
+
ox = Math.round((cs.width - os.width) / gridX) * gridX,
|
3169 |
+
oy = Math.round((cs.height - os.height) / gridY) * gridY,
|
3170 |
+
newWidth = os.width + ox,
|
3171 |
+
newHeight = os.height + oy,
|
3172 |
+
isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
|
3173 |
+
isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
|
3174 |
+
isMinWidth = o.minWidth && (o.minWidth > newWidth),
|
3175 |
+
isMinHeight = o.minHeight && (o.minHeight > newHeight);
|
3176 |
+
|
3177 |
+
o.grid = grid;
|
3178 |
+
|
3179 |
+
if (isMinWidth) {
|
3180 |
+
newWidth = newWidth + gridX;
|
3181 |
+
}
|
3182 |
+
if (isMinHeight) {
|
3183 |
+
newHeight = newHeight + gridY;
|
3184 |
+
}
|
3185 |
+
if (isMaxWidth) {
|
3186 |
+
newWidth = newWidth - gridX;
|
3187 |
+
}
|
3188 |
+
if (isMaxHeight) {
|
3189 |
+
newHeight = newHeight - gridY;
|
3190 |
+
}
|
3191 |
|
3192 |
if (/^(se|s|e)$/.test(a)) {
|
3193 |
+
that.size.width = newWidth;
|
3194 |
+
that.size.height = newHeight;
|
3195 |
+
} else if (/^(ne)$/.test(a)) {
|
3196 |
+
that.size.width = newWidth;
|
3197 |
+
that.size.height = newHeight;
|
3198 |
+
that.position.top = op.top - oy;
|
3199 |
+
} else if (/^(sw)$/.test(a)) {
|
3200 |
+
that.size.width = newWidth;
|
3201 |
+
that.size.height = newHeight;
|
3202 |
+
that.position.left = op.left - ox;
|
3203 |
+
} else {
|
3204 |
+
that.size.width = newWidth;
|
3205 |
+
that.size.height = newHeight;
|
3206 |
+
that.position.top = op.top - oy;
|
3207 |
+
that.position.left = op.left - ox;
|
|
|
|
|
|
|
3208 |
}
|
3209 |
}
|
3210 |
|
3211 |
});
|
3212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3213 |
})(jQuery);
|
3214 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3215 |
(function( $, undefined ) {
|
3216 |
|
3217 |
$.widget("ui.selectable", $.ui.mouse, {
|
3218 |
+
version: "1.10.2",
|
3219 |
options: {
|
3220 |
+
appendTo: "body",
|
3221 |
autoRefresh: true,
|
3222 |
distance: 0,
|
3223 |
+
filter: "*",
|
3224 |
+
tolerance: "touch",
|
3225 |
+
|
3226 |
+
// callbacks
|
3227 |
+
selected: null,
|
3228 |
+
selecting: null,
|
3229 |
+
start: null,
|
3230 |
+
stop: null,
|
3231 |
+
unselected: null,
|
3232 |
+
unselecting: null
|
3233 |
},
|
3234 |
_create: function() {
|
3235 |
+
var selectees,
|
3236 |
+
that = this;
|
3237 |
|
3238 |
this.element.addClass("ui-selectable");
|
3239 |
|
3240 |
this.dragged = false;
|
3241 |
|
3242 |
// cache selectee children based on filter
|
|
|
3243 |
this.refresh = function() {
|
3244 |
+
selectees = $(that.options.filter, that.element[0]);
|
3245 |
selectees.addClass("ui-selectee");
|
3246 |
selectees.each(function() {
|
3247 |
+
var $this = $(this),
|
3248 |
+
pos = $this.offset();
|
3249 |
$.data(this, "selectable-item", {
|
3250 |
element: this,
|
3251 |
$element: $this,
|
3254 |
right: pos.left + $this.outerWidth(),
|
3255 |
bottom: pos.top + $this.outerHeight(),
|
3256 |
startselected: false,
|
3257 |
+
selected: $this.hasClass("ui-selected"),
|
3258 |
+
selecting: $this.hasClass("ui-selecting"),
|
3259 |
+
unselecting: $this.hasClass("ui-unselecting")
|
3260 |
});
|
3261 |
});
|
3262 |
};
|
3269 |
this.helper = $("<div class='ui-selectable-helper'></div>");
|
3270 |
},
|
3271 |
|
3272 |
+
_destroy: function() {
|
3273 |
this.selectees
|
3274 |
.removeClass("ui-selectee")
|
3275 |
.removeData("selectable-item");
|
3276 |
this.element
|
3277 |
+
.removeClass("ui-selectable ui-selectable-disabled");
|
|
|
|
|
3278 |
this._mouseDestroy();
|
|
|
|
|
3279 |
},
|
3280 |
|
3281 |
_mouseStart: function(event) {
|
3282 |
+
var that = this,
|
3283 |
+
options = this.options;
|
3284 |
|
3285 |
this.opos = [event.pageX, event.pageY];
|
3286 |
|
3287 |
+
if (this.options.disabled) {
|
3288 |
return;
|
3289 |
+
}
|
|
|
3290 |
|
3291 |
this.selectees = $(options.filter, this.element[0]);
|
3292 |
|
3295 |
$(options.appendTo).append(this.helper);
|
3296 |
// position helper (lasso)
|
3297 |
this.helper.css({
|
3298 |
+
"left": event.pageX,
|
3299 |
+
"top": event.pageY,
|
3300 |
"width": 0,
|
3301 |
"height": 0
|
3302 |
});
|
3305 |
this.refresh();
|
3306 |
}
|
3307 |
|
3308 |
+
this.selectees.filter(".ui-selected").each(function() {
|
3309 |
var selectee = $.data(this, "selectable-item");
|
3310 |
selectee.startselected = true;
|
3311 |
if (!event.metaKey && !event.ctrlKey) {
|
3312 |
+
selectee.$element.removeClass("ui-selected");
|
3313 |
selectee.selected = false;
|
3314 |
+
selectee.$element.addClass("ui-unselecting");
|
3315 |
selectee.unselecting = true;
|
3316 |
// selectable UNSELECTING callback
|
3317 |
+
that._trigger("unselecting", event, {
|
3318 |
unselecting: selectee.element
|
3319 |
});
|
3320 |
}
|
3321 |
});
|
3322 |
|
3323 |
+
$(event.target).parents().addBack().each(function() {
|
3324 |
+
var doSelect,
|
3325 |
+
selectee = $.data(this, "selectable-item");
|
3326 |
if (selectee) {
|
3327 |
+
doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
|
3328 |
selectee.$element
|
3329 |
.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
|
3330 |
.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
|
3333 |
selectee.selected = doSelect;
|
3334 |
// selectable (UN)SELECTING callback
|
3335 |
if (doSelect) {
|
3336 |
+
that._trigger("selecting", event, {
|
3337 |
selecting: selectee.element
|
3338 |
});
|
3339 |
} else {
|
3340 |
+
that._trigger("unselecting", event, {
|
3341 |
unselecting: selectee.element
|
3342 |
});
|
3343 |
}
|
3348 |
},
|
3349 |
|
3350 |
_mouseDrag: function(event) {
|
3351 |
+
|
3352 |
this.dragged = true;
|
3353 |
|
3354 |
+
if (this.options.disabled) {
|
3355 |
return;
|
3356 |
+
}
|
3357 |
|
3358 |
+
var tmp,
|
3359 |
+
that = this,
|
3360 |
+
options = this.options,
|
3361 |
+
x1 = this.opos[0],
|
3362 |
+
y1 = this.opos[1],
|
3363 |
+
x2 = event.pageX,
|
3364 |
+
y2 = event.pageY;
|
3365 |
|
3366 |
+
if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
|
3367 |
+
if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
|
|
|
3368 |
this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
|
3369 |
|
3370 |
this.selectees.each(function() {
|
3371 |
+
var selectee = $.data(this, "selectable-item"),
|
3372 |
+
hit = false;
|
3373 |
+
|
3374 |
//prevent helper from being selected if appendTo: selectable
|
3375 |
+
if (!selectee || selectee.element === that.element[0]) {
|
3376 |
return;
|
3377 |
+
}
|
3378 |
+
|
3379 |
+
if (options.tolerance === "touch") {
|
3380 |
hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
|
3381 |
+
} else if (options.tolerance === "fit") {
|
3382 |
hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
|
3383 |
}
|
3384 |
|
3385 |
if (hit) {
|
3386 |
// SELECT
|
3387 |
if (selectee.selected) {
|
3388 |
+
selectee.$element.removeClass("ui-selected");
|
3389 |
selectee.selected = false;
|
3390 |
}
|
3391 |
if (selectee.unselecting) {
|
3392 |
+
selectee.$element.removeClass("ui-unselecting");
|
3393 |
selectee.unselecting = false;
|
3394 |
}
|
3395 |
if (!selectee.selecting) {
|
3396 |
+
selectee.$element.addClass("ui-selecting");
|
3397 |
selectee.selecting = true;
|
3398 |
// selectable SELECTING callback
|
3399 |
+
that._trigger("selecting", event, {
|
3400 |
selecting: selectee.element
|
3401 |
});
|
3402 |
}
|
3404 |
// UNSELECT
|
3405 |
if (selectee.selecting) {
|
3406 |
if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
|
3407 |
+
selectee.$element.removeClass("ui-selecting");
|
3408 |
selectee.selecting = false;
|
3409 |
+
selectee.$element.addClass("ui-selected");
|
3410 |
selectee.selected = true;
|
3411 |
} else {
|
3412 |
+
selectee.$element.removeClass("ui-selecting");
|
3413 |
selectee.selecting = false;
|
3414 |
if (selectee.startselected) {
|
3415 |
+
selectee.$element.addClass("ui-unselecting");
|
3416 |
selectee.unselecting = true;
|
3417 |
}
|
3418 |
// selectable UNSELECTING callback
|
3419 |
+
that._trigger("unselecting", event, {
|
3420 |
unselecting: selectee.element
|
3421 |
});
|
3422 |
}
|
3423 |
}
|
3424 |
if (selectee.selected) {
|
3425 |
if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
|
3426 |
+
selectee.$element.removeClass("ui-selected");
|
3427 |
selectee.selected = false;
|
3428 |
|
3429 |
+
selectee.$element.addClass("ui-unselecting");
|
3430 |
selectee.unselecting = true;
|
3431 |
// selectable UNSELECTING callback
|
3432 |
+
that._trigger("unselecting", event, {
|
3433 |
unselecting: selectee.element
|
3434 |
});
|
3435 |
}
|
3441 |
},
|
3442 |
|
3443 |
_mouseStop: function(event) {
|
3444 |
+
var that = this;
|
3445 |
|
3446 |
this.dragged = false;
|
3447 |
|
3448 |
+
$(".ui-unselecting", this.element[0]).each(function() {
|
|
|
|
|
3449 |
var selectee = $.data(this, "selectable-item");
|
3450 |
+
selectee.$element.removeClass("ui-unselecting");
|
3451 |
selectee.unselecting = false;
|
3452 |
selectee.startselected = false;
|
3453 |
+
that._trigger("unselected", event, {
|
3454 |
unselected: selectee.element
|
3455 |
});
|
3456 |
});
|
3457 |
+
$(".ui-selecting", this.element[0]).each(function() {
|
3458 |
var selectee = $.data(this, "selectable-item");
|
3459 |
+
selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
|
3460 |
selectee.selecting = false;
|
3461 |
selectee.selected = true;
|
3462 |
selectee.startselected = true;
|
3463 |
+
that._trigger("selected", event, {
|
3464 |
selected: selectee.element
|
3465 |
});
|
3466 |
});
|
3473 |
|
3474 |
});
|
3475 |
|
|
|
|
|
|
|
|
|
3476 |
})(jQuery);
|
3477 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3478 |
(function( $, undefined ) {
|
3479 |
|
3480 |
+
/*jshint loopfunc: true */
|
3481 |
+
|
3482 |
+
function isOverAxis( x, reference, size ) {
|
3483 |
+
return ( x > reference ) && ( x < ( reference + size ) );
|
3484 |
+
}
|
3485 |
+
|
3486 |
+
function isFloating(item) {
|
3487 |
+
return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
|
3488 |
+
}
|
3489 |
+
|
3490 |
$.widget("ui.sortable", $.ui.mouse, {
|
3491 |
+
version: "1.10.2",
|
3492 |
widgetEventPrefix: "sort",
|
3493 |
+
ready: false,
|
3494 |
options: {
|
3495 |
appendTo: "parent",
|
3496 |
axis: false,
|
3497 |
connectWith: false,
|
3498 |
containment: false,
|
3499 |
+
cursor: "auto",
|
3500 |
cursorAt: false,
|
3501 |
dropOnEmpty: true,
|
3502 |
forcePlaceholderSize: false,
|
3504 |
grid: false,
|
3505 |
handle: false,
|
3506 |
helper: "original",
|
3507 |
+
items: "> *",
|
3508 |
opacity: false,
|
3509 |
placeholder: false,
|
3510 |
revert: false,
|
3513 |
scrollSpeed: 20,
|
3514 |
scope: "default",
|
3515 |
tolerance: "intersect",
|
3516 |
+
zIndex: 1000,
|
3517 |
+
|
3518 |
+
// callbacks
|
3519 |
+
activate: null,
|
3520 |
+
beforeStop: null,
|
3521 |
+
change: null,
|
3522 |
+
deactivate: null,
|
3523 |
+
out: null,
|
3524 |
+
over: null,
|
3525 |
+
receive: null,
|
3526 |
+
remove: null,
|
3527 |
+
sort: null,
|
3528 |
+
start: null,
|
3529 |
+
stop: null,
|
3530 |
+
update: null
|
3531 |
},
|
3532 |
_create: function() {
|
3533 |
|
3539 |
this.refresh();
|
3540 |
|
3541 |
//Let's determine if the items are being displayed horizontally
|
3542 |
+
this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
|
3543 |
|
3544 |
//Let's determine the parent's offset
|
3545 |
this.offset = this.element.offset();
|
3547 |
//Initialize mouse events for interaction
|
3548 |
this._mouseInit();
|
3549 |
|
3550 |
+
//We're ready to go
|
3551 |
+
this.ready = true;
|
3552 |
+
|
3553 |
},
|
3554 |
|
3555 |
+
_destroy: function() {
|
3556 |
this.element
|
3557 |
.removeClass("ui-sortable ui-sortable-disabled");
|
3558 |
this._mouseDestroy();
|
3559 |
|
3560 |
+
for ( var i = this.items.length - 1; i >= 0; i-- ) {
|
3561 |
this.items[i].item.removeData(this.widgetName + "-item");
|
3562 |
+
}
|
3563 |
|
3564 |
return this;
|
3565 |
},
|
3567 |
_setOption: function(key, value){
|
3568 |
if ( key === "disabled" ) {
|
3569 |
this.options[ key ] = value;
|
3570 |
+
|
3571 |
+
this.widget().toggleClass( "ui-sortable-disabled", !!value );
|
|
|
3572 |
} else {
|
3573 |
// Don't call widget base _setOption for disable as it adds ui-state-disabled class
|
3574 |
$.Widget.prototype._setOption.apply(this, arguments);
|
3576 |
},
|
3577 |
|
3578 |
_mouseCapture: function(event, overrideHandle) {
|
3579 |
+
var currentItem = null,
|
3580 |
+
validHandle = false,
|
3581 |
+
that = this;
|
3582 |
|
3583 |
if (this.reverting) {
|
3584 |
return false;
|
3585 |
}
|
3586 |
|
3587 |
+
if(this.options.disabled || this.options.type === "static") {
|
3588 |
+
return false;
|
3589 |
+
}
|
3590 |
|
3591 |
//We have to refresh the items data once first
|
3592 |
this._refreshItems(event);
|
3593 |
|
3594 |
//Find out if the clicked node (or one of its parents) is a actual item in this.items
|
3595 |
+
$(event.target).parents().each(function() {
|
3596 |
+
if($.data(this, that.widgetName + "-item") === that) {
|
3597 |
currentItem = $(this);
|
3598 |
return false;
|
3599 |
}
|
3600 |
});
|
3601 |
+
if($.data(event.target, that.widgetName + "-item") === that) {
|
3602 |
+
currentItem = $(event.target);
|
3603 |
+
}
|
3604 |
|
3605 |
+
if(!currentItem) {
|
3606 |
+
return false;
|
3607 |
+
}
|
3608 |
if(this.options.handle && !overrideHandle) {
|
3609 |
+
$(this.options.handle, currentItem).find("*").addBack().each(function() {
|
3610 |
+
if(this === event.target) {
|
3611 |
+
validHandle = true;
|
3612 |
+
}
|
3613 |
+
});
|
3614 |
+
if(!validHandle) {
|
3615 |
+
return false;
|
3616 |
+
}
|
3617 |
}
|
3618 |
|
3619 |
this.currentItem = currentItem;
|
3624 |
|
3625 |
_mouseStart: function(event, overrideHandle, noActivation) {
|
3626 |
|
3627 |
+
var i, body,
|
3628 |
+
o = this.options;
|
3629 |
+
|
3630 |
this.currentContainer = this;
|
3631 |
|
3632 |
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
|
3656 |
left: this.offset.left - this.margins.left
|
3657 |
};
|
3658 |
|
|
|
|
|
|
|
|
|
|
|
3659 |
$.extend(this.offset, {
|
3660 |
click: { //Where the click happened, relative to the element
|
3661 |
left: event.pageX - this.offset.left,
|
3665 |
relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
|
3666 |
});
|
3667 |
|
3668 |
+
// Only after we got the offset, we can change the helper's position to absolute
|
3669 |
+
// TODO: Still need to figure out a way to make relative sorting possible
|
3670 |
+
this.helper.css("position", "absolute");
|
3671 |
+
this.cssPosition = this.helper.css("position");
|
3672 |
+
|
3673 |
//Generate the original position
|
3674 |
this.originalPosition = this._generatePosition(event);
|
3675 |
this.originalPageX = event.pageX;
|
3676 |
this.originalPageY = event.pageY;
|
3677 |
|
3678 |
+
//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
|
3679 |
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
|
3680 |
|
3681 |
//Cache the former DOM position
|
3682 |
this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
|
3683 |
|
3684 |
//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
|
3685 |
+
if(this.helper[0] !== this.currentItem[0]) {
|
3686 |
this.currentItem.hide();
|
3687 |
}
|
3688 |
|
3690 |
this._createPlaceholder();
|
3691 |
|
3692 |
//Set a containment if given in the options
|
3693 |
+
if(o.containment) {
|
3694 |
this._setContainment();
|
3695 |
+
}
|
3696 |
+
|
3697 |
+
if( o.cursor && o.cursor !== "auto" ) { // cursor option
|
3698 |
+
body = this.document.find( "body" );
|
3699 |
|
3700 |
+
// support: IE
|
3701 |
+
this.storedCursor = body.css( "cursor" );
|
3702 |
+
body.css( "cursor", o.cursor );
|
3703 |
+
|
3704 |
+
this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
|
3705 |
}
|
3706 |
|
3707 |
if(o.opacity) { // opacity option
|
3708 |
+
if (this.helper.css("opacity")) {
|
3709 |
+
this._storedOpacity = this.helper.css("opacity");
|
3710 |
+
}
|
3711 |
this.helper.css("opacity", o.opacity);
|
3712 |
}
|
3713 |
|
3714 |
if(o.zIndex) { // zIndex option
|
3715 |
+
if (this.helper.css("zIndex")) {
|
3716 |
+
this._storedZIndex = this.helper.css("zIndex");
|
3717 |
+
}
|
3718 |
this.helper.css("zIndex", o.zIndex);
|
3719 |
}
|
3720 |
|
3721 |
//Prepare scrolling
|
3722 |
+
if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
|
3723 |
this.overflowOffset = this.scrollParent.offset();
|
3724 |
+
}
|
3725 |
|
3726 |
//Call callbacks
|
3727 |
this._trigger("start", event, this._uiHash());
|
3728 |
|
3729 |
//Recache the helper size
|
3730 |
+
if(!this._preserveHelperProportions) {
|
3731 |
this._cacheHelperProportions();
|
3732 |
+
}
|
3733 |
|
3734 |
|
3735 |
+
//Post "activate" events to possible containers
|
3736 |
+
if( !noActivation ) {
|
3737 |
+
for ( i = this.containers.length - 1; i >= 0; i-- ) {
|
3738 |
+
this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
|
3739 |
+
}
|
3740 |
}
|
3741 |
|
3742 |
//Prepare possible droppables
|
3743 |
+
if($.ui.ddmanager) {
|
3744 |
$.ui.ddmanager.current = this;
|
3745 |
+
}
|
3746 |
|
3747 |
+
if ($.ui.ddmanager && !o.dropBehaviour) {
|
3748 |
$.ui.ddmanager.prepareOffsets(this, event);
|
3749 |
+
}
|
3750 |
|
3751 |
this.dragging = true;
|
3752 |
|
3757 |
},
|
3758 |
|
3759 |
_mouseDrag: function(event) {
|
3760 |
+
var i, item, itemElement, intersection,
|
3761 |
+
o = this.options,
|
3762 |
+
scrolled = false;
|
3763 |
|
3764 |
//Compute the helpers position
|
3765 |
this.position = this._generatePosition(event);
|
3771 |
|
3772 |
//Do scrolling
|
3773 |
if(this.options.scroll) {
|
3774 |
+
if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
|
|
|
3775 |
|
3776 |
+
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
|
3777 |
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
|
3778 |
+
} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
|
3779 |
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
|
3780 |
+
}
|
3781 |
|
3782 |
+
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
|
3783 |
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
|
3784 |
+
} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
|
3785 |
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
|
3786 |
+
}
|
3787 |
|
3788 |
} else {
|
3789 |
|
3790 |
+
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
|
3791 |
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
3792 |
+
} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
|
3793 |
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
3794 |
+
}
|
3795 |
|
3796 |
+
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
|
3797 |
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
3798 |
+
} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
|
3799 |
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
3800 |
+
}
|
3801 |
|
3802 |
}
|
3803 |
|
3804 |
+
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
|
3805 |
$.ui.ddmanager.prepareOffsets(this, event);
|
3806 |
+
}
|
3807 |
}
|
3808 |
|
3809 |
//Regenerate the absolute position used for position checks
|
3810 |
this.positionAbs = this._convertPositionTo("absolute");
|
3811 |
|
3812 |
//Set the helper position
|
3813 |
+
if(!this.options.axis || this.options.axis !== "y") {
|
3814 |
+
this.helper[0].style.left = this.position.left+"px";
|
3815 |
+
}
|
3816 |
+
if(!this.options.axis || this.options.axis !== "x") {
|
3817 |
+
this.helper[0].style.top = this.position.top+"px";
|
3818 |
+
}
|
3819 |
|
3820 |
//Rearrange
|
3821 |
+
for (i = this.items.length - 1; i >= 0; i--) {
|
3822 |
|
3823 |
//Cache variables and intersection, continue if no intersection
|
3824 |
+
item = this.items[i];
|
3825 |
+
itemElement = item.item[0];
|
3826 |
+
intersection = this._intersectsWithPointer(item);
|
3827 |
+
if (!intersection) {
|
3828 |
+
continue;
|
3829 |
+
}
|
3830 |
+
|
3831 |
+
// Only put the placeholder inside the current Container, skip all
|
3832 |
+
// items form other containers. This works because when moving
|
3833 |
+
// an item from one container to another the
|
3834 |
+
// currentContainer is switched before the placeholder is moved.
|
3835 |
+
//
|
3836 |
+
// Without this moving items in "sub-sortables" can cause the placeholder to jitter
|
3837 |
+
// beetween the outer and inner container.
|
3838 |
+
if (item.instance !== this.currentContainer) {
|
3839 |
+
continue;
|
3840 |
+
}
|
3841 |
+
|
3842 |
+
// cannot intersect with itself
|
3843 |
+
// no useless actions that have been done before
|
3844 |
+
// no action if the item moved is the parent of the item checked
|
3845 |
+
if (itemElement !== this.currentItem[0] &&
|
3846 |
+
this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
|
3847 |
+
!$.contains(this.placeholder[0], itemElement) &&
|
3848 |
+
(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
|
3849 |
) {
|
3850 |
|
3851 |
+
this.direction = intersection === 1 ? "down" : "up";
|
3852 |
|
3853 |
+
if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
|
3854 |
this._rearrange(event, item);
|
3855 |
} else {
|
3856 |
break;
|
3865 |
this._contactContainers(event);
|
3866 |
|
3867 |
//Interconnect with droppables
|
3868 |
+
if($.ui.ddmanager) {
|
3869 |
+
$.ui.ddmanager.drag(this, event);
|
3870 |
+
}
|
3871 |
|
3872 |
//Call callbacks
|
3873 |
+
this._trigger("sort", event, this._uiHash());
|
3874 |
|
3875 |
this.lastPositionAbs = this.positionAbs;
|
3876 |
return false;
|
3879 |
|
3880 |
_mouseStop: function(event, noPropagation) {
|
3881 |
|
3882 |
+
if(!event) {
|
3883 |
+
return;
|
3884 |
+
}
|
3885 |
|
3886 |
//If we are using droppables, inform the manager about the drop
|
3887 |
+
if ($.ui.ddmanager && !this.options.dropBehaviour) {
|
3888 |
$.ui.ddmanager.drop(this, event);
|
3889 |
+
}
|
3890 |
|
3891 |
if(this.options.revert) {
|
3892 |
+
var that = this,
|
3893 |
+
cur = this.placeholder.offset(),
|
3894 |
+
axis = this.options.axis,
|
3895 |
+
animation = {};
|
3896 |
|
3897 |
+
if ( !axis || axis === "x" ) {
|
3898 |
+
animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
|
3899 |
+
}
|
3900 |
+
if ( !axis || axis === "y" ) {
|
3901 |
+
animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
|
3902 |
+
}
|
3903 |
+
this.reverting = true;
|
3904 |
+
$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
|
3905 |
+
that._clear(event);
|
3906 |
});
|
3907 |
} else {
|
3908 |
this._clear(event, noPropagation);
|
3914 |
|
3915 |
cancel: function() {
|
3916 |
|
|
|
|
|
3917 |
if(this.dragging) {
|
3918 |
|
3919 |
this._mouseUp({ target: null });
|
3920 |
|
3921 |
+
if(this.options.helper === "original") {
|
3922 |
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
|
3923 |
+
} else {
|
3924 |
this.currentItem.show();
|
3925 |
+
}
|
3926 |
|
3927 |
//Post deactivating events to containers
|
3928 |
for (var i = this.containers.length - 1; i >= 0; i--){
|
3929 |
+
this.containers[i]._trigger("deactivate", null, this._uiHash(this));
|
3930 |
if(this.containers[i].containerCache.over) {
|
3931 |
+
this.containers[i]._trigger("out", null, this._uiHash(this));
|
3932 |
this.containers[i].containerCache.over = 0;
|
3933 |
}
|
3934 |
}
|
3937 |
|
3938 |
if (this.placeholder) {
|
3939 |
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
|
3940 |
+
if(this.placeholder[0].parentNode) {
|
3941 |
+
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
|
3942 |
+
}
|
3943 |
+
if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
|
3944 |
+
this.helper.remove();
|
3945 |
+
}
|
3946 |
|
3947 |
$.extend(this, {
|
3948 |
helper: null,
|
3964 |
|
3965 |
serialize: function(o) {
|
3966 |
|
3967 |
+
var items = this._getItemsAsjQuery(o && o.connected),
|
3968 |
+
str = [];
|
3969 |
+
o = o || {};
|
3970 |
|
3971 |
$(items).each(function() {
|
3972 |
+
var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
|
3973 |
+
if (res) {
|
3974 |
+
str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
|
3975 |
+
}
|
3976 |
});
|
3977 |
|
3978 |
if(!str.length && o.key) {
|
3979 |
+
str.push(o.key + "=");
|
3980 |
}
|
3981 |
|
3982 |
+
return str.join("&");
|
3983 |
|
3984 |
},
|
3985 |
|
3986 |
toArray: function(o) {
|
3987 |
|
3988 |
+
var items = this._getItemsAsjQuery(o && o.connected),
|
3989 |
+
ret = [];
|
3990 |
+
|
3991 |
+
o = o || {};
|
3992 |
|
3993 |
+
items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
|
3994 |
return ret;
|
3995 |
|
3996 |
},
|
4001 |
var x1 = this.positionAbs.left,
|
4002 |
x2 = x1 + this.helperProportions.width,
|
4003 |
y1 = this.positionAbs.top,
|
4004 |
+
y2 = y1 + this.helperProportions.height,
|
4005 |
+
l = item.left,
|
|
|
4006 |
r = l + item.width,
|
4007 |
t = item.top,
|
4008 |
+
b = t + item.height,
|
4009 |
+
dyClick = this.offset.click.top,
|
4010 |
+
dxClick = this.offset.click.left,
|
4011 |
+
isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
|
4012 |
+
|
4013 |
+
if ( this.options.tolerance === "pointer" ||
|
4014 |
+
this.options.forcePointerForContainers ||
|
4015 |
+
(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
|
|
|
|
|
4016 |
) {
|
4017 |
return isOverElement;
|
4018 |
} else {
|
4019 |
|
4020 |
+
return (l < x1 + (this.helperProportions.width / 2) && // Right Half
|
4021 |
+
x2 - (this.helperProportions.width / 2) < r && // Left Half
|
4022 |
+
t < y1 + (this.helperProportions.height / 2) && // Bottom Half
|
4023 |
+
y2 - (this.helperProportions.height / 2) < b ); // Top Half
|
4024 |
|
4025 |
}
|
4026 |
},
|
4027 |
|
4028 |
_intersectsWithPointer: function(item) {
|
4029 |
|
4030 |
+
var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
|
4031 |
+
isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
|
4032 |
isOverElement = isOverElementHeight && isOverElementWidth,
|
4033 |
verticalDirection = this._getDragVerticalDirection(),
|
4034 |
horizontalDirection = this._getDragHorizontalDirection();
|
4035 |
|
4036 |
+
if (!isOverElement) {
|
4037 |
return false;
|
4038 |
+
}
|
4039 |
|
4040 |
return this.floating ?
|
4041 |
+
( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
|
4042 |
+
: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
|
4043 |
|
4044 |
},
|
4045 |
|
4046 |
_intersectsWithSides: function(item) {
|
4047 |
|
4048 |
+
var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
|
4049 |
+
isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
|
4050 |
verticalDirection = this._getDragVerticalDirection(),
|
4051 |
horizontalDirection = this._getDragHorizontalDirection();
|
4052 |
|
4053 |
if (this.floating && horizontalDirection) {
|
4054 |
+
return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
|
4055 |
} else {
|
4056 |
+
return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
|
4057 |
}
|
4058 |
|
4059 |
},
|
4060 |
|
4061 |
_getDragVerticalDirection: function() {
|
4062 |
var delta = this.positionAbs.top - this.lastPositionAbs.top;
|
4063 |
+
return delta !== 0 && (delta > 0 ? "down" : "up");
|
4064 |
},
|
4065 |
|
4066 |
_getDragHorizontalDirection: function() {
|
4067 |
var delta = this.positionAbs.left - this.lastPositionAbs.left;
|
4068 |
+
return delta !== 0 && (delta > 0 ? "right" : "left");
|
4069 |
},
|
4070 |
|
4071 |
refresh: function(event) {
|
4076 |
|
4077 |
_connectWith: function() {
|
4078 |
var options = this.options;
|
4079 |
+
return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
|
|
|
|
|
4080 |
},
|
4081 |
+
|
4082 |
_getItemsAsjQuery: function(connected) {
|
4083 |
|
4084 |
+
var i, j, cur, inst,
|
4085 |
+
items = [],
|
4086 |
+
queries = [],
|
4087 |
+
connectWith = this._connectWith();
|
4088 |
|
4089 |
if(connectWith && connected) {
|
4090 |
+
for (i = connectWith.length - 1; i >= 0; i--){
|
4091 |
+
cur = $(connectWith[i]);
|
4092 |
+
for ( j = cur.length - 1; j >= 0; j--){
|
4093 |
+
inst = $.data(cur[j], this.widgetFullName);
|
4094 |
+
if(inst && inst !== this && !inst.options.disabled) {
|
4095 |
+
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]);
|
4096 |
}
|
4097 |
+
}
|
4098 |
+
}
|
4099 |
}
|
4100 |
|
4101 |
+
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]);
|
4102 |
|
4103 |
+
for (i = queries.length - 1; i >= 0; i--){
|
4104 |
queries[i][0].each(function() {
|
4105 |
items.push(this);
|
4106 |
});
|
4107 |
+
}
|
4108 |
|
4109 |
return $(items);
|
4110 |
|
4114 |
|
4115 |
var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
|
4116 |
|
4117 |
+
this.items = $.grep(this.items, function (item) {
|
|
|
4118 |
for (var j=0; j < list.length; j++) {
|
4119 |
+
if(list[j] === item.item[0]) {
|
4120 |
+
return false;
|
4121 |
+
}
|
4122 |
+
}
|
4123 |
+
return true;
|
4124 |
+
});
|
4125 |
|
4126 |
},
|
4127 |
|
4129 |
|
4130 |
this.items = [];
|
4131 |
this.containers = [this];
|
4132 |
+
|
4133 |
+
var i, j, cur, inst, targetData, _queries, item, queriesLength,
|
4134 |
+
items = this.items,
|
4135 |
+
queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
|
4136 |
+
connectWith = this._connectWith();
|
4137 |
+
|
4138 |
+
if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
|
4139 |
+
for (i = connectWith.length - 1; i >= 0; i--){
|
4140 |
+
cur = $(connectWith[i]);
|
4141 |
+
for (j = cur.length - 1; j >= 0; j--){
|
4142 |
+
inst = $.data(cur[j], this.widgetFullName);
|
4143 |
+
if(inst && inst !== this && !inst.options.disabled) {
|
4144 |
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
|
4145 |
this.containers.push(inst);
|
4146 |
}
|
4147 |
+
}
|
4148 |
+
}
|
4149 |
}
|
4150 |
|
4151 |
+
for (i = queries.length - 1; i >= 0; i--) {
|
4152 |
+
targetData = queries[i][1];
|
4153 |
+
_queries = queries[i][0];
|
4154 |
|
4155 |
+
for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
|
4156 |
+
item = $(_queries[j]);
|
4157 |
|
4158 |
+
item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
|
4159 |
|
4160 |
items.push({
|
4161 |
item: item,
|
4163 |
width: 0, height: 0,
|
4164 |
left: 0, top: 0
|
4165 |
});
|
4166 |
+
}
|
4167 |
+
}
|
4168 |
|
4169 |
},
|
4170 |
|
4175 |
this.offset.parent = this._getParentOffset();
|
4176 |
}
|
4177 |
|
4178 |
+
var i, item, t, p;
|
4179 |
+
|
4180 |
+
for (i = this.items.length - 1; i >= 0; i--){
|
4181 |
+
item = this.items[i];
|
4182 |
|
4183 |
//We ignore calculating positions of all connected containers when we're not over them
|
4184 |
+
if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
|
4185 |
continue;
|
4186 |
+
}
|
4187 |
|
4188 |
+
t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
|
4189 |
|
4190 |
if (!fast) {
|
4191 |
item.width = t.outerWidth();
|
4192 |
item.height = t.outerHeight();
|
4193 |
}
|
4194 |
|
4195 |
+
p = t.offset();
|
4196 |
item.left = p.left;
|
4197 |
item.top = p.top;
|
4198 |
+
}
|
4199 |
|
4200 |
if(this.options.custom && this.options.custom.refreshContainers) {
|
4201 |
this.options.custom.refreshContainers.call(this);
|
4202 |
} else {
|
4203 |
+
for (i = this.containers.length - 1; i >= 0; i--){
|
4204 |
+
p = this.containers[i].element.offset();
|
4205 |
this.containers[i].containerCache.left = p.left;
|
4206 |
this.containers[i].containerCache.top = p.top;
|
4207 |
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
|
4208 |
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
|
4209 |
+
}
|
4210 |
}
|
4211 |
|
4212 |
return this;
|
4213 |
},
|
4214 |
|
4215 |
_createPlaceholder: function(that) {
|
4216 |
+
that = that || this;
|
4217 |
+
var className,
|
4218 |
+
o = that.options;
|
4219 |
|
4220 |
+
if(!o.placeholder || o.placeholder.constructor === String) {
|
4221 |
+
className = o.placeholder;
|
|
|
|
|
4222 |
o.placeholder = {
|
4223 |
element: function() {
|
4224 |
|
4225 |
+
var nodeName = that.currentItem[0].nodeName.toLowerCase(),
|
4226 |
+
element = $( that.document[0].createElement( nodeName ) )
|
4227 |
+
.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
|
4228 |
+
.removeClass("ui-sortable-helper");
|
4229 |
+
|
4230 |
+
if ( nodeName === "tr" ) {
|
4231 |
+
// Use a high colspan to force the td to expand the full
|
4232 |
+
// width of the table (browsers are smart enough to
|
4233 |
+
// handle this properly)
|
4234 |
+
element.append( "<td colspan='99'> </td>" );
|
4235 |
+
} else if ( nodeName === "img" ) {
|
4236 |
+
element.attr( "src", that.currentItem.attr( "src" ) );
|
4237 |
+
}
|
4238 |
|
4239 |
+
if ( !className ) {
|
4240 |
+
element.css( "visibility", "hidden" );
|
4241 |
+
}
|
4242 |
|
4243 |
+
return element;
|
4244 |
},
|
4245 |
update: function(container, p) {
|
4246 |
|
4247 |
// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
|
4248 |
// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
|
4249 |
+
if(className && !o.forcePlaceholderSize) {
|
4250 |
+
return;
|
4251 |
+
}
|
4252 |
|
4253 |
//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
|
4254 |
+
if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
|
4255 |
+
if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
|
4256 |
}
|
4257 |
};
|
4258 |
}
|
4259 |
|
4260 |
//Create the placeholder
|
4261 |
+
that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
|
4262 |
|
4263 |
//Append it after the actual current item
|
4264 |
+
that.currentItem.after(that.placeholder);
|
4265 |
|
4266 |
//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
|
4267 |
+
o.placeholder.update(that, that.placeholder);
|
4268 |
|
4269 |
},
|
4270 |
|
4271 |
_contactContainers: function(event) {
|
4272 |
+
var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
|
4273 |
+
innermostContainer = null,
|
4274 |
+
innermostIndex = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4275 |
|
4276 |
+
// get innermost container that intersects with item
|
4277 |
+
for (i = this.containers.length - 1; i >= 0; i--) {
|
4278 |
|
4279 |
+
// never consider a container that's located within the item itself
|
4280 |
+
if($.contains(this.currentItem[0], this.containers[i].element[0])) {
|
4281 |
+
continue;
|
4282 |
+
}
|
4283 |
+
|
4284 |
+
if(this._intersectsWith(this.containers[i].containerCache)) {
|
4285 |
+
|
4286 |
+
// if we've already found a container and it's more "inner" than this, then continue
|
4287 |
+
if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
|
4288 |
continue;
|
4289 |
+
}
|
4290 |
|
4291 |
+
innermostContainer = this.containers[i];
|
4292 |
innermostIndex = i;
|
4293 |
+
|
4294 |
} else {
|
4295 |
+
// container doesn't intersect. trigger "out" event if necessary
|
4296 |
if(this.containers[i].containerCache.over) {
|
4297 |
this.containers[i]._trigger("out", event, this._uiHash(this));
|
4298 |
this.containers[i].containerCache.over = 0;
|
4300 |
}
|
4301 |
|
4302 |
}
|
4303 |
+
|
4304 |
+
// if no intersecting containers found, return
|
4305 |
+
if(!innermostContainer) {
|
4306 |
+
return;
|
4307 |
+
}
|
4308 |
|
4309 |
// move the item into the container if it's not there already
|
4310 |
if(this.containers.length === 1) {
|
4311 |
+
if (!this.containers[innermostIndex].containerCache.over) {
|
4312 |
+
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
|
4313 |
+
this.containers[innermostIndex].containerCache.over = 1;
|
4314 |
+
}
|
4315 |
+
} else {
|
4316 |
+
|
4317 |
+
//When entering a new container, we will find the item with the least distance and append our item near it
|
4318 |
+
dist = 10000;
|
4319 |
+
itemWithLeastDistance = null;
|
4320 |
+
floating = innermostContainer.floating || isFloating(this.currentItem);
|
4321 |
+
posProperty = floating ? "left" : "top";
|
4322 |
+
sizeProperty = floating ? "width" : "height";
|
4323 |
+
base = this.positionAbs[posProperty] + this.offset.click[posProperty];
|
4324 |
+
for (j = this.items.length - 1; j >= 0; j--) {
|
4325 |
+
if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
|
4326 |
+
continue;
|
4327 |
+
}
|
4328 |
+
if(this.items[j].item[0] === this.currentItem[0]) {
|
4329 |
+
continue;
|
4330 |
+
}
|
4331 |
+
if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
|
4332 |
+
continue;
|
4333 |
+
}
|
4334 |
+
cur = this.items[j].item.offset()[posProperty];
|
4335 |
+
nearBottom = false;
|
4336 |
+
if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
|
4337 |
+
nearBottom = true;
|
4338 |
+
cur += this.items[j][sizeProperty];
|
4339 |
+
}
|
4340 |
+
|
4341 |
+
if(Math.abs(cur - base) < dist) {
|
4342 |
+
dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
|
4343 |
+
this.direction = nearBottom ? "up": "down";
|
4344 |
+
}
|
4345 |
+
}
|
4346 |
+
|
4347 |
+
//Check if dropOnEmpty is enabled
|
4348 |
+
if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
|
4349 |
+
return;
|
4350 |
+
}
|
4351 |
+
|
4352 |
+
if(this.currentContainer === this.containers[innermostIndex]) {
|
4353 |
+
return;
|
4354 |
+
}
|
4355 |
+
|
4356 |
+
itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
|
4357 |
+
this._trigger("change", event, this._uiHash());
|
4358 |
+
this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
|
4359 |
+
this.currentContainer = this.containers[innermostIndex];
|
4360 |
+
|
4361 |
+
//Update the placeholder
|
4362 |
+
this.options.placeholder.update(this.currentContainer, this.placeholder);
|
4363 |
+
|
4364 |
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
|
4365 |
this.containers[innermostIndex].containerCache.over = 1;
|
4366 |
+
}
|
4367 |
+
|
4368 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4369 |
},
|
4370 |
|
4371 |
_createHelper: function(event) {
|
4372 |
|
4373 |
+
var o = this.options,
|
4374 |
+
helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
|
4375 |
|
4376 |
+
//Add the helper to the DOM if that didn't happen already
|
4377 |
+
if(!helper.parents("body").length) {
|
4378 |
+
$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
|
4379 |
+
}
|
4380 |
|
4381 |
+
if(helper[0] === this.currentItem[0]) {
|
4382 |
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") };
|
4383 |
+
}
|
4384 |
|
4385 |
+
if(!helper[0].style.width || o.forceHelperSize) {
|
4386 |
+
helper.width(this.currentItem.width());
|
4387 |
+
}
|
4388 |
+
if(!helper[0].style.height || o.forceHelperSize) {
|
4389 |
+
helper.height(this.currentItem.height());
|
4390 |
+
}
|
4391 |
|
4392 |
return helper;
|
4393 |
|
4394 |
},
|
4395 |
|
4396 |
_adjustOffsetFromHelper: function(obj) {
|
4397 |
+
if (typeof obj === "string") {
|
4398 |
+
obj = obj.split(" ");
|
4399 |
}
|
4400 |
if ($.isArray(obj)) {
|
4401 |
obj = {left: +obj[0], top: +obj[1] || 0};
|
4402 |
}
|
4403 |
+
if ("left" in obj) {
|
4404 |
this.offset.click.left = obj.left + this.margins.left;
|
4405 |
}
|
4406 |
+
if ("right" in obj) {
|
4407 |
this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
|
4408 |
}
|
4409 |
+
if ("top" in obj) {
|
4410 |
this.offset.click.top = obj.top + this.margins.top;
|
4411 |
}
|
4412 |
+
if ("bottom" in obj) {
|
4413 |
this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
|
4414 |
}
|
4415 |
},
|
4425 |
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
|
4426 |
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
|
4427 |
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
|
4428 |
+
if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
|
4429 |
po.left += this.scrollParent.scrollLeft();
|
4430 |
po.top += this.scrollParent.scrollTop();
|
4431 |
}
|
4432 |
|
4433 |
+
// This needs to be actually done for all browsers, since pageX/pageY includes this information
|
4434 |
+
// with an ugly IE fix
|
4435 |
+
if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
|
4436 |
po = { top: 0, left: 0 };
|
4437 |
+
}
|
4438 |
|
4439 |
return {
|
4440 |
top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
|
4445 |
|
4446 |
_getRelativeOffset: function() {
|
4447 |
|
4448 |
+
if(this.cssPosition === "relative") {
|
4449 |
var p = this.currentItem.position();
|
4450 |
return {
|
4451 |
top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
|
4473 |
|
4474 |
_setContainment: function() {
|
4475 |
|
4476 |
+
var ce, co, over,
|
4477 |
+
o = this.options;
|
4478 |
+
if(o.containment === "parent") {
|
4479 |
+
o.containment = this.helper[0].parentNode;
|
4480 |
+
}
|
4481 |
+
if(o.containment === "document" || o.containment === "window") {
|
4482 |
+
this.containment = [
|
4483 |
+
0 - this.offset.relative.left - this.offset.parent.left,
|
4484 |
+
0 - this.offset.relative.top - this.offset.parent.top,
|
4485 |
+
$(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
|
4486 |
+
($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
|
4487 |
+
];
|
4488 |
+
}
|
4489 |
|
4490 |
if(!(/^(document|window|parent)$/).test(o.containment)) {
|
4491 |
+
ce = $(o.containment)[0];
|
4492 |
+
co = $(o.containment).offset();
|
4493 |
+
over = ($(ce).css("overflow") !== "hidden");
|
4494 |
|
4495 |
this.containment = [
|
4496 |
co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
|
4504 |
|
4505 |
_convertPositionTo: function(d, pos) {
|
4506 |
|
4507 |
+
if(!pos) {
|
4508 |
+
pos = this.position;
|
4509 |
+
}
|
4510 |
+
var mod = d === "absolute" ? 1 : -1,
|
4511 |
+
scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
|
4512 |
+
scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
|
4513 |
|
4514 |
return {
|
4515 |
top: (
|
4516 |
+
pos.top + // The absolute mouse position
|
4517 |
+
this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
|
4518 |
+
this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
|
4519 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
|
4520 |
),
|
4521 |
left: (
|
4522 |
+
pos.left + // The absolute mouse position
|
4523 |
+
this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
|
4524 |
+
this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
|
4525 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
|
4526 |
)
|
4527 |
};
|
4528 |
|
4530 |
|
4531 |
_generatePosition: function(event) {
|
4532 |
|
4533 |
+
var top, left,
|
4534 |
+
o = this.options,
|
4535 |
+
pageX = event.pageX,
|
4536 |
+
pageY = event.pageY,
|
4537 |
+
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);
|
4538 |
|
4539 |
// This is another very weird special case that only happens for relative elements:
|
4540 |
// 1. If the css position is relative
|
4541 |
// 2. and the scroll parent is the document or similar to the offset parent
|
4542 |
// we have to refresh the relative offset during the scroll so there are no jumps
|
4543 |
+
if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
|
4544 |
this.offset.relative = this._getRelativeOffset();
|
4545 |
}
|
4546 |
|
|
|
|
|
|
|
4547 |
/*
|
4548 |
* - Position constraining -
|
4549 |
* Constrain the position to a mix of grid, containment.
|
4552 |
if(this.originalPosition) { //If we are not dragging yet, we won't check for options
|
4553 |
|
4554 |
if(this.containment) {
|
4555 |
+
if(event.pageX - this.offset.click.left < this.containment[0]) {
|
4556 |
+
pageX = this.containment[0] + this.offset.click.left;
|
4557 |
+
}
|
4558 |
+
if(event.pageY - this.offset.click.top < this.containment[1]) {
|
4559 |
+
pageY = this.containment[1] + this.offset.click.top;
|
4560 |
+
}
|
4561 |
+
if(event.pageX - this.offset.click.left > this.containment[2]) {
|
4562 |
+
pageX = this.containment[2] + this.offset.click.left;
|
4563 |
+
}
|
4564 |
+
if(event.pageY - this.offset.click.top > this.containment[3]) {
|
4565 |
+
pageY = this.containment[3] + this.offset.click.top;
|
4566 |
+
}
|
4567 |
}
|
4568 |
|
4569 |
if(o.grid) {
|
4570 |
+
top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
|
4571 |
+
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;
|
4572 |
|
4573 |
+
left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
|
4574 |
+
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;
|
4575 |
}
|
4576 |
|
4577 |
}
|
4578 |
|
4579 |
return {
|
4580 |
top: (
|
4581 |
+
pageY - // The absolute mouse position
|
4582 |
+
this.offset.click.top - // Click offset (relative to the element)
|
4583 |
+
this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
|
4584 |
+
this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
|
4585 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
|
4586 |
),
|
4587 |
left: (
|
4588 |
+
pageX - // The absolute mouse position
|
4589 |
+
this.offset.click.left - // Click offset (relative to the element)
|
4590 |
+
this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
|
4591 |
+
this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
|
4592 |
+
( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
|
4593 |
)
|
4594 |
};
|
4595 |
|
4597 |
|
4598 |
_rearrange: function(event, i, a, hardRefresh) {
|
4599 |
|
4600 |
+
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));
|
4601 |
|
4602 |
//Various things done here to improve the performance:
|
4603 |
// 1. we create a setTimeout, that calls refreshPositions
|
4605 |
// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
|
4606 |
// 4. this lets only the last addition to the timeout stack through
|
4607 |
this.counter = this.counter ? ++this.counter : 1;
|
4608 |
+
var counter = this.counter;
|
4609 |
|
4610 |
+
this._delay(function() {
|
4611 |
+
if(counter === this.counter) {
|
4612 |
+
this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
|
4613 |
+
}
|
4614 |
+
});
|
4615 |
|
4616 |
},
|
4617 |
|
4620 |
this.reverting = false;
|
4621 |
// We delay all events that have to be triggered to after the point where the placeholder has been removed and
|
4622 |
// everything else normalized again
|
4623 |
+
var i,
|
4624 |
+
delayedTriggers = [];
|
4625 |
|
4626 |
// We first have to update the dom position of the actual currentItem
|
4627 |
// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
|
4628 |
+
if(!this._noFinalSort && this.currentItem.parent().length) {
|
4629 |
+
this.placeholder.before(this.currentItem);
|
4630 |
+
}
|
4631 |
this._noFinalSort = null;
|
4632 |
|
4633 |
+
if(this.helper[0] === this.currentItem[0]) {
|
4634 |
+
for(i in this._storedCSS) {
|
4635 |
+
if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
|
4636 |
+
this._storedCSS[i] = "";
|
4637 |
+
}
|
4638 |
}
|
4639 |
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
|
4640 |
} else {
|
4641 |
this.currentItem.show();
|
4642 |
}
|
4643 |
|
4644 |
+
if(this.fromOutside && !noPropagation) {
|
4645 |
+
delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
|
4646 |
+
}
|
4647 |
+
if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
|
4648 |
+
delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
|
4649 |
+
}
|
4650 |
+
|
4651 |
+
// Check if the items Container has Changed and trigger appropriate
|
4652 |
+
// events.
|
4653 |
+
if (this !== this.currentContainer) {
|
4654 |
+
if(!noPropagation) {
|
4655 |
+
delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
|
4656 |
+
delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
|
4657 |
+
delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
|
4658 |
+
}
|
4659 |
+
}
|
4660 |
+
|
4661 |
|
4662 |
//Post events to containers
|
4663 |
+
for (i = this.containers.length - 1; i >= 0; i--){
|
4664 |
+
if(!noPropagation) {
|
4665 |
+
delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
|
4666 |
+
}
|
4667 |
if(this.containers[i].containerCache.over) {
|
4668 |
delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
|
4669 |
this.containers[i].containerCache.over = 0;
|
4671 |
}
|
4672 |
|
4673 |
//Do what was originally in plugins
|
4674 |
+
if ( this.storedCursor ) {
|
4675 |
+
this.document.find( "body" ).css( "cursor", this.storedCursor );
|
4676 |
+
this.storedStylesheet.remove();
|
4677 |
+
}
|
4678 |
+
if(this._storedOpacity) {
|
4679 |
+
this.helper.css("opacity", this._storedOpacity);
|
4680 |
+
}
|
4681 |
+
if(this._storedZIndex) {
|
4682 |
+
this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
|
4683 |
+
}
|
4684 |
|
4685 |
this.dragging = false;
|
4686 |
if(this.cancelHelperRemoval) {
|
4687 |
if(!noPropagation) {
|
4688 |
this._trigger("beforeStop", event, this._uiHash());
|
4689 |
+
for (i=0; i < delayedTriggers.length; i++) {
|
4690 |
+
delayedTriggers[i].call(this, event);
|
4691 |
+
} //Trigger all delayed events
|
4692 |
this._trigger("stop", event, this._uiHash());
|
4693 |
}
|
4694 |
+
|
4695 |
+
this.fromOutside = false;
|
4696 |
return false;
|
4697 |
}
|
4698 |
|
4699 |
+
if(!noPropagation) {
|
4700 |
+
this._trigger("beforeStop", event, this._uiHash());
|
4701 |
+
}
|
4702 |
|
4703 |
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
|
4704 |
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
|
4705 |
|
4706 |
+
if(this.helper[0] !== this.currentItem[0]) {
|
4707 |
+
this.helper.remove();
|
4708 |
+
}
|
4709 |
+
this.helper = null;
|
4710 |
|
4711 |
if(!noPropagation) {
|
4712 |
+
for (i=0; i < delayedTriggers.length; i++) {
|
4713 |
+
delayedTriggers[i].call(this, event);
|
4714 |
+
} //Trigger all delayed events
|
4715 |
this._trigger("stop", event, this._uiHash());
|
4716 |
}
|
4717 |
|
4726 |
}
|
4727 |
},
|
4728 |
|
4729 |
+
_uiHash: function(_inst) {
|
4730 |
+
var inst = _inst || this;
|
4731 |
return {
|
4732 |
+
helper: inst.helper,
|
4733 |
+
placeholder: inst.placeholder || $([]),
|
4734 |
+
position: inst.position,
|
4735 |
+
originalPosition: inst.originalPosition,
|
4736 |
+
offset: inst.positionAbs,
|
4737 |
+
item: inst.currentItem,
|
4738 |
+
sender: _inst ? _inst.element : null
|
4739 |
};
|
4740 |
}
|
4741 |
|
4742 |
});
|
4743 |
|
|
|
|
|
|
|
|
|
4744 |
})(jQuery);
|
4745 |
+
|
4746 |
+
(function($, undefined) {
|
4747 |
+
|
4748 |
+
var dataSpace = "ui-effects-";
|
4749 |
+
|
4750 |
+
$.effects = {
|
4751 |
+
effect: {}
|
4752 |
+
};
|
4753 |
+
|
4754 |
+
/*!
|
4755 |
+
* jQuery Color Animations v2.1.2
|
4756 |
+
* https://github.com/jquery/jquery-color
|
4757 |
*
|
4758 |
+
* Copyright 2013 jQuery Foundation and other contributors
|
4759 |
+
* Released under the MIT license.
|
4760 |
* http://jquery.org/license
|
4761 |
*
|
4762 |
+
* Date: Wed Jan 16 08:47:09 2013 -0600
|
|
|
|
|
|
|
|
|
4763 |
*/
|
4764 |
+
(function( jQuery, undefined ) {
|
4765 |
+
|
4766 |
+
var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
|
4767 |
+
|
4768 |
+
// plusequals test for += 100 -= 100
|
4769 |
+
rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
|
4770 |
+
// a set of RE's that can match strings and generate color tuples.
|
4771 |
+
stringParsers = [{
|
4772 |
+
re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
|
4773 |
+
parse: function( execResult ) {
|
4774 |
+
return [
|
4775 |
+
execResult[ 1 ],
|
4776 |
+
execResult[ 2 ],
|
4777 |
+
execResult[ 3 ],
|
4778 |
+
execResult[ 4 ]
|
4779 |
+
];
|
4780 |
+
}
|
4781 |
+
}, {
|
4782 |
+
re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
|
4783 |
+
parse: function( execResult ) {
|
4784 |
+
return [
|
4785 |
+
execResult[ 1 ] * 2.55,
|
4786 |
+
execResult[ 2 ] * 2.55,
|
4787 |
+
execResult[ 3 ] * 2.55,
|
4788 |
+
execResult[ 4 ]
|
4789 |
+
];
|
4790 |
+
}
|
4791 |
+
}, {
|
4792 |
+
// this regex ignores A-F because it's compared against an already lowercased string
|
4793 |
+
re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
|
4794 |
+
parse: function( execResult ) {
|
4795 |
+
return [
|
4796 |
+
parseInt( execResult[ 1 ], 16 ),
|
4797 |
+
parseInt( execResult[ 2 ], 16 ),
|
4798 |
+
parseInt( execResult[ 3 ], 16 )
|
4799 |
+
];
|
4800 |
+
}
|
4801 |
+
}, {
|
4802 |
+
// this regex ignores A-F because it's compared against an already lowercased string
|
4803 |
+
re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
|
4804 |
+
parse: function( execResult ) {
|
4805 |
+
return [
|
4806 |
+
parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
|
4807 |
+
parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
|
4808 |
+
parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
|
4809 |
+
];
|
4810 |
+
}
|
4811 |
+
}, {
|
4812 |
+
re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
|
4813 |
+
space: "hsla",
|
4814 |
+
parse: function( execResult ) {
|
4815 |
+
return [
|
4816 |
+
execResult[ 1 ],
|
4817 |
+
execResult[ 2 ] / 100,
|
4818 |
+
execResult[ 3 ] / 100,
|
4819 |
+
execResult[ 4 ]
|
4820 |
+
];
|
4821 |
+
}
|
4822 |
+
}],
|
4823 |
+
|
4824 |
+
// jQuery.Color( )
|
4825 |
+
color = jQuery.Color = function( color, green, blue, alpha ) {
|
4826 |
+
return new jQuery.Color.fn.parse( color, green, blue, alpha );
|
4827 |
+
},
|
4828 |
+
spaces = {
|
4829 |
+
rgba: {
|
4830 |
+
props: {
|
4831 |
+
red: {
|
4832 |
+
idx: 0,
|
4833 |
+
type: "byte"
|
4834 |
+
},
|
4835 |
+
green: {
|
4836 |
+
idx: 1,
|
4837 |
+
type: "byte"
|
4838 |
+
},
|
4839 |
+
blue: {
|
4840 |
+
idx: 2,
|
4841 |
+
type: "byte"
|
4842 |
+
}
|
4843 |
+
}
|
4844 |
+
},
|
4845 |
|
4846 |
+
hsla: {
|
4847 |
+
props: {
|
4848 |
+
hue: {
|
4849 |
+
idx: 0,
|
4850 |
+
type: "degrees"
|
4851 |
+
},
|
4852 |
+
saturation: {
|
4853 |
+
idx: 1,
|
4854 |
+
type: "percent"
|
4855 |
+
},
|
4856 |
+
lightness: {
|
4857 |
+
idx: 2,
|
4858 |
+
type: "percent"
|
4859 |
+
}
|
4860 |
+
}
|
4861 |
+
}
|
4862 |
+
},
|
4863 |
+
propTypes = {
|
4864 |
+
"byte": {
|
4865 |
+
floor: true,
|
4866 |
+
max: 255
|
4867 |
},
|
4868 |
+
"percent": {
|
4869 |
+
max: 1
|
4870 |
+
},
|
4871 |
+
"degrees": {
|
4872 |
+
mod: 360,
|
4873 |
+
floor: true
|
4874 |
}
|
4875 |
},
|
4876 |
+
support = color.support = {},
|
4877 |
|
4878 |
+
// element for support tests
|
4879 |
+
supportElem = jQuery( "<p>" )[ 0 ],
|
|
|
4880 |
|
4881 |
+
// colors = jQuery.Color.names
|
4882 |
+
colors,
|
4883 |
|
4884 |
+
// local aliases of functions called often
|
4885 |
+
each = jQuery.each;
|
|
|
|
|
|
|
|
|
4886 |
|
4887 |
+
// determine rgba support immediately
|
4888 |
+
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
|
4889 |
+
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
|
4890 |
+
|
4891 |
+
// define cache name and alpha properties
|
4892 |
+
// for rgba and hsla spaces
|
4893 |
+
each( spaces, function( spaceName, space ) {
|
4894 |
+
space.cache = "_" + spaceName;
|
4895 |
+
space.props.alpha = {
|
4896 |
+
idx: 3,
|
4897 |
+
type: "percent",
|
4898 |
+
def: 1
|
4899 |
+
};
|
4900 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4901 |
|
4902 |
+
function clamp( value, prop, allowEmpty ) {
|
4903 |
+
var type = propTypes[ prop.type ] || {};
|
4904 |
|
4905 |
+
if ( value == null ) {
|
4906 |
+
return (allowEmpty || !prop.def) ? null : prop.def;
|
4907 |
+
}
|
4908 |
+
|
4909 |
+
// ~~ is an short way of doing floor for positive numbers
|
4910 |
+
value = type.floor ? ~~value : parseFloat( value );
|
4911 |
+
|
4912 |
+
// IE will pass in empty strings as value for alpha,
|
4913 |
+
// which will hit this case
|
4914 |
+
if ( isNaN( value ) ) {
|
4915 |
+
return prop.def;
|
4916 |
+
}
|
4917 |
+
|
4918 |
+
if ( type.mod ) {
|
4919 |
+
// we add mod before modding to make sure that negatives values
|
4920 |
+
// get converted properly: -10 -> 350
|
4921 |
+
return (value + type.mod) % type.mod;
|
4922 |
+
}
|
4923 |
+
|
4924 |
+
// for now all property types without mod have min and max
|
4925 |
+
return 0 > value ? 0 : type.max < value ? type.max : value;
|
4926 |
+
}
|
4927 |
+
|
4928 |
+
function stringParse( string ) {
|
4929 |
+
var inst = color(),
|
4930 |
+
rgba = inst._rgba = [];
|
4931 |
+
|
4932 |
+
string = string.toLowerCase();
|
4933 |
+
|
4934 |
+
each( stringParsers, function( i, parser ) {
|
4935 |
+
var parsed,
|
4936 |
+
match = parser.re.exec( string ),
|
4937 |
+
values = match && parser.parse( match ),
|
4938 |
+
spaceName = parser.space || "rgba";
|
4939 |
+
|
4940 |
+
if ( values ) {
|
4941 |
+
parsed = inst[ spaceName ]( values );
|
4942 |
+
|
4943 |
+
// if this was an rgba parse the assignment might happen twice
|
4944 |
+
// oh well....
|
4945 |
+
inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
|
4946 |
+
rgba = inst._rgba = parsed._rgba;
|
4947 |
+
|
4948 |
+
// exit each( stringParsers ) here because we matched
|
4949 |
+
return false;
|
4950 |
}
|
4951 |
+
});
|
4952 |
|
4953 |
+
// Found a stringParser that handled it
|
4954 |
+
if ( rgba.length ) {
|
|
|
|
|
|
|
4955 |
|
4956 |
+
// if this came from a parsed string, force "transparent" when alpha is 0
|
4957 |
+
// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
|
4958 |
+
if ( rgba.join() === "0,0,0,0" ) {
|
4959 |
+
jQuery.extend( rgba, colors.transparent );
|
4960 |
+
}
|
4961 |
+
return inst;
|
4962 |
+
}
|
4963 |
|
4964 |
+
// named colors
|
4965 |
+
return colors[ string ];
|
4966 |
+
}
|
|
|
|
|
|
|
|
|
4967 |
|
4968 |
+
color.fn = jQuery.extend( color.prototype, {
|
4969 |
+
parse: function( red, green, blue, alpha ) {
|
4970 |
+
if ( red === undefined ) {
|
4971 |
+
this._rgba = [ null, null, null, null ];
|
4972 |
+
return this;
|
4973 |
+
}
|
4974 |
+
if ( red.jquery || red.nodeType ) {
|
4975 |
+
red = jQuery( red ).css( green );
|
4976 |
+
green = undefined;
|
4977 |
+
}
|
4978 |
|
4979 |
+
var inst = this,
|
4980 |
+
type = jQuery.type( red ),
|
4981 |
+
rgba = this._rgba = [];
|
4982 |
+
|
4983 |
+
// more than 1 argument specified - assume ( red, green, blue, alpha )
|
4984 |
+
if ( green !== undefined ) {
|
4985 |
+
red = [ red, green, blue, alpha ];
|
4986 |
+
type = "array";
|
|
|
|
|
4987 |
}
|
4988 |
|
4989 |
+
if ( type === "string" ) {
|
4990 |
+
return this.parse( stringParse( red ) || colors._default );
|
|
|
4991 |
}
|
4992 |
|
4993 |
+
if ( type === "array" ) {
|
4994 |
+
each( spaces.rgba.props, function( key, prop ) {
|
4995 |
+
rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
|
|
|
4996 |
});
|
4997 |
+
return this;
|
4998 |
}
|
|
|
4999 |
|
5000 |
+
if ( type === "object" ) {
|
5001 |
+
if ( red instanceof color ) {
|
5002 |
+
each( spaces, function( spaceName, space ) {
|
5003 |
+
if ( red[ space.cache ] ) {
|
5004 |
+
inst[ space.cache ] = red[ space.cache ].slice();
|
5005 |
+
}
|
5006 |
+
});
|
5007 |
+
} else {
|
5008 |
+
each( spaces, function( spaceName, space ) {
|
5009 |
+
var cache = space.cache;
|
5010 |
+
each( space.props, function( key, prop ) {
|
5011 |
+
|
5012 |
+
// if the cache doesn't exist, and we know how to convert
|
5013 |
+
if ( !inst[ cache ] && space.to ) {
|
5014 |
+
|
5015 |
+
// if the value was null, we don't need to copy it
|
5016 |
+
// if the key was alpha, we don't need to copy it either
|
5017 |
+
if ( key === "alpha" || red[ key ] == null ) {
|
5018 |
+
return;
|
5019 |
+
}
|
5020 |
+
inst[ cache ] = space.to( inst._rgba );
|
5021 |
+
}
|
5022 |
+
|
5023 |
+
// this is the only case where we allow nulls for ALL properties.
|
5024 |
+
// call clamp with alwaysAllowEmpty
|
5025 |
+
inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
|
5026 |
+
});
|
5027 |
+
|
5028 |
+
// everything defined but alpha?
|
5029 |
+
if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
|
5030 |
+
// use the default of 1
|
5031 |
+
inst[ cache ][ 3 ] = 1;
|
5032 |
+
if ( space.from ) {
|
5033 |
+
inst._rgba = space.from( inst[ cache ] );
|
5034 |
+
}
|
5035 |
+
}
|
5036 |
+
});
|
5037 |
+
}
|
5038 |
+
return this;
|
5039 |
}
|
5040 |
},
|
5041 |
+
is: function( compare ) {
|
5042 |
+
var is = color( compare ),
|
5043 |
+
same = true,
|
5044 |
+
inst = this;
|
5045 |
|
5046 |
+
each( spaces, function( _, space ) {
|
5047 |
+
var localCache,
|
5048 |
+
isCache = is[ space.cache ];
|
5049 |
+
if (isCache) {
|
5050 |
+
localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
|
5051 |
+
each( space.props, function( _, prop ) {
|
5052 |
+
if ( isCache[ prop.idx ] != null ) {
|
5053 |
+
same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
|
5054 |
+
return same;
|
5055 |
+
}
|
5056 |
+
});
|
5057 |
+
}
|
5058 |
+
return same;
|
5059 |
+
});
|
5060 |
+
return same;
|
5061 |
},
|
5062 |
+
_space: function() {
|
5063 |
+
var used = [],
|
5064 |
+
inst = this;
|
5065 |
+
each( spaces, function( spaceName, space ) {
|
5066 |
+
if ( inst[ space.cache ] ) {
|
5067 |
+
used.push( spaceName );
|
5068 |
+
}
|
5069 |
+
});
|
5070 |
+
return used.pop();
|
5071 |
+
},
|
5072 |
+
transition: function( other, distance ) {
|
5073 |
+
var end = color( other ),
|
5074 |
+
spaceName = end._space(),
|
5075 |
+
space = spaces[ spaceName ],
|
5076 |
+
startColor = this.alpha() === 0 ? color( "transparent" ) : this,
|
5077 |
+
start = startColor[ space.cache ] || space.to( startColor._rgba ),
|
5078 |
+
result = start.slice();
|
5079 |
+
|
5080 |
+
end = end[ space.cache ];
|
5081 |
+
each( space.props, function( key, prop ) {
|
5082 |
+
var index = prop.idx,
|
5083 |
+
startValue = start[ index ],
|
5084 |
+
endValue = end[ index ],
|
5085 |
+
type = propTypes[ prop.type ] || {};
|
5086 |
+
|
5087 |
+
// if null, don't override start value
|
5088 |
+
if ( endValue === null ) {
|
5089 |
+
return;
|
5090 |
+
}
|
5091 |
+
// if null - use end
|
5092 |
+
if ( startValue === null ) {
|
5093 |
+
result[ index ] = endValue;
|
5094 |
+
} else {
|
5095 |
+
if ( type.mod ) {
|
5096 |
+
if ( endValue - startValue > type.mod / 2 ) {
|
5097 |
+
startValue += type.mod;
|
5098 |
+
} else if ( startValue - endValue > type.mod / 2 ) {
|
5099 |
+
startValue -= type.mod;
|
5100 |
+
}
|
5101 |
+
}
|
5102 |
+
result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
|
5103 |
+
}
|
5104 |
+
});
|
5105 |
+
return this[ spaceName ]( result );
|
5106 |
+
},
|
5107 |
+
blend: function( opaque ) {
|
5108 |
+
// if we are already opaque - return ourself
|
5109 |
+
if ( this._rgba[ 3 ] === 1 ) {
|
5110 |
+
return this;
|
5111 |
+
}
|
5112 |
|
5113 |
+
var rgb = this._rgba.slice(),
|
5114 |
+
a = rgb.pop(),
|
5115 |
+
blend = color( opaque )._rgba;
|
|
|
|
|
|
|
5116 |
|
5117 |
+
return color( jQuery.map( rgb, function( v, i ) {
|
5118 |
+
return ( 1 - a ) * blend[ i ] + a * v;
|
5119 |
+
}));
|
5120 |
+
},
|
5121 |
+
toRgbaString: function() {
|
5122 |
+
var prefix = "rgba(",
|
5123 |
+
rgba = jQuery.map( this._rgba, function( v, i ) {
|
5124 |
+
return v == null ? ( i > 2 ? 1 : 0 ) : v;
|
5125 |
+
});
|
5126 |
|
5127 |
+
if ( rgba[ 3 ] === 1 ) {
|
5128 |
+
rgba.pop();
|
5129 |
+
prefix = "rgb(";
|
|
|
|
|
|
|
|
|
|
|
5130 |
}
|
5131 |
|
5132 |
+
return prefix + rgba.join() + ")";
|
5133 |
},
|
5134 |
+
toHslaString: function() {
|
5135 |
+
var prefix = "hsla(",
|
5136 |
+
hsla = jQuery.map( this.hsla(), function( v, i ) {
|
5137 |
+
if ( v == null ) {
|
5138 |
+
v = i > 2 ? 1 : 0;
|
5139 |
+
}
|
5140 |
|
5141 |
+
// catch 1 and 2
|
5142 |
+
if ( i && i < 3 ) {
|
5143 |
+
v = Math.round( v * 100 ) + "%";
|
5144 |
+
}
|
5145 |
+
return v;
|
5146 |
+
});
|
5147 |
+
|
5148 |
+
if ( hsla[ 3 ] === 1 ) {
|
5149 |
+
hsla.pop();
|
5150 |
+
prefix = "hsl(";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5151 |
}
|
5152 |
+
return prefix + hsla.join() + ")";
|
5153 |
},
|
5154 |
+
toHexString: function( includeAlpha ) {
|
5155 |
+
var rgba = this._rgba.slice(),
|
5156 |
+
alpha = rgba.pop();
|
5157 |
|
5158 |
+
if ( includeAlpha ) {
|
5159 |
+
rgba.push( ~~( alpha * 255 ) );
|
|
|
5160 |
}
|
5161 |
|
5162 |
+
return "#" + jQuery.map( rgba, function( v ) {
|
|
|
|
|
|
|
5163 |
|
5164 |
+
// default to 0 when nulls exist
|
5165 |
+
v = ( v || 0 ).toString( 16 );
|
5166 |
+
return v.length === 1 ? "0" + v : v;
|
5167 |
+
}).join("");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5168 |
},
|
5169 |
+
toString: function() {
|
5170 |
+
return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
|
5171 |
+
}
|
5172 |
+
});
|
5173 |
+
color.fn.parse.prototype = color.fn;
|
5174 |
|
5175 |
+
// hsla conversions adapted from:
|
5176 |
+
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
|
|
|
5177 |
|
5178 |
+
function hue2rgb( p, q, h ) {
|
5179 |
+
h = ( h + 1 ) % 1;
|
5180 |
+
if ( h * 6 < 1 ) {
|
5181 |
+
return p + (q - p) * h * 6;
|
5182 |
+
}
|
5183 |
+
if ( h * 2 < 1) {
|
5184 |
+
return q;
|
5185 |
+
}
|
5186 |
+
if ( h * 3 < 2 ) {
|
5187 |
+
return p + (q - p) * ((2/3) - h) * 6;
|
5188 |
+
}
|
5189 |
+
return p;
|
5190 |
+
}
|
5191 |
|
5192 |
+
spaces.hsla.to = function ( rgba ) {
|
5193 |
+
if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
|
5194 |
+
return [ null, null, null, rgba[ 3 ] ];
|
5195 |
+
}
|
5196 |
+
var r = rgba[ 0 ] / 255,
|
5197 |
+
g = rgba[ 1 ] / 255,
|
5198 |
+
b = rgba[ 2 ] / 255,
|
5199 |
+
a = rgba[ 3 ],
|
5200 |
+
max = Math.max( r, g, b ),
|
5201 |
+
min = Math.min( r, g, b ),
|
5202 |
+
diff = max - min,
|
5203 |
+
add = max + min,
|
5204 |
+
l = add * 0.5,
|
5205 |
+
h, s;
|
5206 |
+
|
5207 |
+
if ( min === max ) {
|
5208 |
+
h = 0;
|
5209 |
+
} else if ( r === max ) {
|
5210 |
+
h = ( 60 * ( g - b ) / diff ) + 360;
|
5211 |
+
} else if ( g === max ) {
|
5212 |
+
h = ( 60 * ( b - r ) / diff ) + 120;
|
5213 |
+
} else {
|
5214 |
+
h = ( 60 * ( r - g ) / diff ) + 240;
|
5215 |
+
}
|
5216 |
|
5217 |
+
// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
|
5218 |
+
// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
|
5219 |
+
if ( diff === 0 ) {
|
5220 |
+
s = 0;
|
5221 |
+
} else if ( l <= 0.5 ) {
|
5222 |
+
s = diff / add;
|
5223 |
+
} else {
|
5224 |
+
s = diff / ( 2 - add );
|
5225 |
+
}
|
5226 |
+
return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
|
5227 |
+
};
|
|
|
|
|
|
|
5228 |
|
5229 |
+
spaces.hsla.from = function ( hsla ) {
|
5230 |
+
if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
|
5231 |
+
return [ null, null, null, hsla[ 3 ] ];
|
5232 |
+
}
|
5233 |
+
var h = hsla[ 0 ] / 360,
|
5234 |
+
s = hsla[ 1 ],
|
5235 |
+
l = hsla[ 2 ],
|
5236 |
+
a = hsla[ 3 ],
|
5237 |
+
q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
|
5238 |
+
p = 2 * l - q;
|
5239 |
+
|
5240 |
+
return [
|
5241 |
+
Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
|
5242 |
+
Math.round( hue2rgb( p, q, h ) * 255 ),
|
5243 |
+
Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
|
5244 |
+
a
|
5245 |
+
];
|
5246 |
+
};
|
5247 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5248 |
|
5249 |
+
each( spaces, function( spaceName, space ) {
|
5250 |
+
var props = space.props,
|
5251 |
+
cache = space.cache,
|
5252 |
+
to = space.to,
|
5253 |
+
from = space.from;
|
5254 |
|
5255 |
+
// makes rgba() and hsla()
|
5256 |
+
color.fn[ spaceName ] = function( value ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5257 |
|
5258 |
+
// generate a cache for this space if it doesn't exist
|
5259 |
+
if ( to && !this[ cache ] ) {
|
5260 |
+
this[ cache ] = to( this._rgba );
|
|
|
|
|
5261 |
}
|
5262 |
+
if ( value === undefined ) {
|
5263 |
+
return this[ cache ].slice();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5264 |
}
|
5265 |
|
5266 |
+
var ret,
|
5267 |
+
type = jQuery.type( value ),
|
5268 |
+
arr = ( type === "array" || type === "object" ) ? value : arguments,
|
5269 |
+
local = this[ cache ].slice();
|
5270 |
+
|
5271 |
+
each( props, function( key, prop ) {
|
5272 |
+
var val = arr[ type === "object" ? key : prop.idx ];
|
5273 |
+
if ( val == null ) {
|
5274 |
+
val = local[ prop.idx ];
|
5275 |
+
}
|
5276 |
+
local[ prop.idx ] = clamp( val, prop );
|
5277 |
+
});
|
5278 |
|
5279 |
+
if ( from ) {
|
5280 |
+
ret = color( from( local ) );
|
5281 |
+
ret[ cache ] = local;
|
5282 |
+
return ret;
|
5283 |
+
} else {
|
5284 |
+
return color( local );
|
5285 |
+
}
|
5286 |
+
};
|
5287 |
|
5288 |
+
// makes red() green() blue() alpha() hue() saturation() lightness()
|
5289 |
+
each( props, function( key, prop ) {
|
5290 |
+
// alpha is included in more than one space
|
5291 |
+
if ( color.fn[ key ] ) {
|
5292 |
return;
|
5293 |
}
|
5294 |
+
color.fn[ key ] = function( value ) {
|
5295 |
+
var vtype = jQuery.type( value ),
|
5296 |
+
fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
|
5297 |
+
local = this[ fn ](),
|
5298 |
+
cur = local[ prop.idx ],
|
5299 |
+
match;
|
5300 |
|
5301 |
+
if ( vtype === "undefined" ) {
|
5302 |
+
return cur;
|
5303 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5304 |
|
5305 |
+
if ( vtype === "function" ) {
|
5306 |
+
value = value.call( this, cur );
|
5307 |
+
vtype = jQuery.type( value );
|
5308 |
+
}
|
5309 |
+
if ( value == null && prop.empty ) {
|
5310 |
+
return this;
|
5311 |
+
}
|
5312 |
+
if ( vtype === "string" ) {
|
5313 |
+
match = rplusequals.exec( value );
|
5314 |
+
if ( match ) {
|
5315 |
+
value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
|
5316 |
+
}
|
5317 |
+
}
|
5318 |
+
local[ prop.idx ] = value;
|
5319 |
+
return this[ fn ]( local );
|
5320 |
+
};
|
5321 |
+
});
|
5322 |
+
});
|
5323 |
|
5324 |
+
// add cssHook and .fx.step function for each named hook.
|
5325 |
+
// accept a space separated string of properties
|
5326 |
+
color.hook = function( hook ) {
|
5327 |
+
var hooks = hook.split( " " );
|
5328 |
+
each( hooks, function( i, hook ) {
|
5329 |
+
jQuery.cssHooks[ hook ] = {
|
5330 |
+
set: function( elem, value ) {
|
5331 |
+
var parsed, curElem,
|
5332 |
+
backgroundColor = "";
|
5333 |
+
|
5334 |
+
if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
|
5335 |
+
value = color( parsed || value );
|
5336 |
+
if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
|
5337 |
+
curElem = hook === "backgroundColor" ? elem.parentNode : elem;
|
5338 |
+
while (
|
5339 |
+
(backgroundColor === "" || backgroundColor === "transparent") &&
|
5340 |
+
curElem && curElem.style
|
5341 |
+
) {
|
5342 |
+
try {
|
5343 |
+
backgroundColor = jQuery.css( curElem, "backgroundColor" );
|
5344 |
+
curElem = curElem.parentNode;
|
5345 |
+
} catch ( e ) {
|
5346 |
+
}
|
5347 |
+
}
|
5348 |
|
5349 |
+
value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
|
5350 |
+
backgroundColor :
|
5351 |
+
"_default" );
|
5352 |
+
}
|
5353 |
|
5354 |
+
value = value.toRgbaString();
|
5355 |
+
}
|
5356 |
+
try {
|
5357 |
+
elem.style[ hook ] = value;
|
5358 |
+
} catch( e ) {
|
5359 |
+
// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
|
5360 |
+
}
|
5361 |
}
|
|
|
5362 |
};
|
5363 |
+
jQuery.fx.step[ hook ] = function( fx ) {
|
5364 |
+
if ( !fx.colorInit ) {
|
5365 |
+
fx.start = color( fx.elem, hook );
|
5366 |
+
fx.end = color( fx.end );
|
5367 |
+
fx.colorInit = true;
|
5368 |
+
}
|
5369 |
+
jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
|
5370 |
+
};
|
5371 |
+
});
|
5372 |
|
5373 |
+
};
|
|
|
5374 |
|
5375 |
+
color.hook( stepHooks );
|
|
|
5376 |
|
5377 |
+
jQuery.cssHooks.borderColor = {
|
5378 |
+
expand: function( value ) {
|
5379 |
+
var expanded = {};
|
5380 |
|
5381 |
+
each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
|
5382 |
+
expanded[ "border" + part + "Color" ] = value;
|
5383 |
+
});
|
5384 |
+
return expanded;
|
5385 |
+
}
|
5386 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5387 |
|
5388 |
+
// Basic color names only.
|
5389 |
+
// Usage of any of the other color names requires adding yourself or including
|
5390 |
+
// jquery.color.svg-names.js.
|
5391 |
+
colors = jQuery.Color.names = {
|
5392 |
+
// 4.1. Basic color keywords
|
5393 |
+
aqua: "#00ffff",
|
5394 |
+
black: "#000000",
|
5395 |
+
blue: "#0000ff",
|
5396 |
+
fuchsia: "#ff00ff",
|
5397 |
+
gray: "#808080",
|
5398 |
+
green: "#008000",
|
5399 |
+
lime: "#00ff00",
|
5400 |
+
maroon: "#800000",
|
5401 |
+
navy: "#000080",
|
5402 |
+
olive: "#808000",
|
5403 |
+
purple: "#800080",
|
5404 |
+
red: "#ff0000",
|
5405 |
+
silver: "#c0c0c0",
|
5406 |
+
teal: "#008080",
|
5407 |
+
white: "#ffffff",
|
5408 |
+
yellow: "#ffff00",
|
5409 |
+
|
5410 |
+
// 4.2.3. "transparent" color keyword
|
5411 |
+
transparent: [ null, null, null, 0 ],
|
5412 |
+
|
5413 |
+
_default: "#ffffff"
|
5414 |
+
};
|
5415 |
|
5416 |
+
})( jQuery );
|
5417 |
+
|
5418 |
+
|
5419 |
+
/******************************************************************************/
|
5420 |
+
/****************************** CLASS ANIMATIONS ******************************/
|
5421 |
+
/******************************************************************************/
|
5422 |
+
(function() {
|
5423 |
|
5424 |
+
var classAnimationActions = [ "add", "remove", "toggle" ],
|
5425 |
+
shorthandStyles = {
|
5426 |
+
border: 1,
|
5427 |
+
borderBottom: 1,
|
5428 |
+
borderColor: 1,
|
5429 |
+
borderLeft: 1,
|
5430 |
+
borderRight: 1,
|
5431 |
+
borderTop: 1,
|
5432 |
+
borderWidth: 1,
|
5433 |
+
margin: 1,
|
5434 |
+
padding: 1
|
5435 |
+
};
|
5436 |
|
5437 |
+
$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
|
5438 |
+
$.fx.step[ prop ] = function( fx ) {
|
5439 |
+
if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
|
5440 |
+
jQuery.style( fx.elem, prop, fx.end );
|
5441 |
+
fx.setAttr = true;
|
5442 |
+
}
|
5443 |
+
};
|
5444 |
+
});
|
5445 |
|
5446 |
+
function getElementStyles( elem ) {
|
5447 |
+
var key, len,
|
5448 |
+
style = elem.ownerDocument.defaultView ?
|
5449 |
+
elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
|
5450 |
+
elem.currentStyle,
|
5451 |
+
styles = {};
|
5452 |
|
5453 |
+
if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
|
5454 |
+
len = style.length;
|
5455 |
+
while ( len-- ) {
|
5456 |
+
key = style[ len ];
|
5457 |
+
if ( typeof style[ key ] === "string" ) {
|
5458 |
+
styles[ $.camelCase( key ) ] = style[ key ];
|
5459 |
}
|
5460 |
+
}
|
5461 |
+
// support: Opera, IE <9
|
5462 |
+
} else {
|
5463 |
+
for ( key in style ) {
|
5464 |
+
if ( typeof style[ key ] === "string" ) {
|
5465 |
+
styles[ key ] = style[ key ];
|
|
|
5466 |
}
|
5467 |
+
}
|
5468 |
+
}
|
5469 |
|
5470 |
+
return styles;
|
5471 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
5472 |
|
|
|
|
|
5473 |
|
5474 |
+
function styleDifference( oldStyle, newStyle ) {
|
5475 |
+
var diff = {},
|
5476 |
+
name, value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5477 |
|
5478 |
+
for ( name in newStyle ) {
|
5479 |
+
value = newStyle[ name ];
|
5480 |
+
if ( oldStyle[ name ] !== value ) {
|
5481 |
+
if ( !shorthandStyles[ name ] ) {
|
5482 |
+
if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
|
5483 |
+
diff[ name ] = value;
|
5484 |
+
}
|
5485 |
+
}
|
5486 |
}
|
5487 |
+
}
|
5488 |
|
5489 |
+
return diff;
|
5490 |
+
}
|
|
|
|
|
|
|
|
|
5491 |
|
5492 |
+
// support: jQuery <1.8
|
5493 |
+
if ( !$.fn.addBack ) {
|
5494 |
+
$.fn.addBack = function( selector ) {
|
5495 |
+
return this.add( selector == null ?
|
5496 |
+
this.prevObject : this.prevObject.filter( selector )
|
5497 |
+
);
|
5498 |
+
};
|
5499 |
+
}
|
5500 |
|
5501 |
+
$.effects.animateClass = function( value, duration, easing, callback ) {
|
5502 |
+
var o = $.speed( duration, easing, callback );
|
|
|
5503 |
|
5504 |
+
return this.queue( function() {
|
5505 |
+
var animated = $( this ),
|
5506 |
+
baseClass = animated.attr( "class" ) || "",
|
5507 |
+
applyClassChange,
|
5508 |
+
allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5509 |
|
5510 |
+
// map the animated objects to store the original styles.
|
5511 |
+
allAnimations = allAnimations.map(function() {
|
5512 |
+
var el = $( this );
|
5513 |
+
return {
|
5514 |
+
el: el,
|
5515 |
+
start: getElementStyles( this )
|
5516 |
+
};
|
5517 |
+
});
|
5518 |
+
|
5519 |
+
// apply class change
|
5520 |
+
applyClassChange = function() {
|
5521 |
+
$.each( classAnimationActions, function(i, action) {
|
5522 |
+
if ( value[ action ] ) {
|
5523 |
+
animated[ action + "Class" ]( value[ action ] );
|
|
|
5524 |
}
|
5525 |
});
|
5526 |
+
};
|
5527 |
+
applyClassChange();
|
5528 |
+
|
5529 |
+
// map all animated objects again - calculate new styles and diff
|
5530 |
+
allAnimations = allAnimations.map(function() {
|
5531 |
+
this.end = getElementStyles( this.el[ 0 ] );
|
5532 |
+
this.diff = styleDifference( this.start, this.end );
|
5533 |
+
return this;
|
5534 |
+
});
|
5535 |
+
|
5536 |
+
// apply original class
|
5537 |
+
animated.attr( "class", baseClass );
|
5538 |
+
|
5539 |
+
// map all animated objects again - this time collecting a promise
|
5540 |
+
allAnimations = allAnimations.map(function() {
|
5541 |
+
var styleInfo = this,
|
5542 |
+
dfd = $.Deferred(),
|
5543 |
+
opts = $.extend({}, o, {
|
5544 |
+
queue: false,
|
5545 |
+
complete: function() {
|
5546 |
+
dfd.resolve( styleInfo );
|
5547 |
+
}
|
5548 |
+
});
|
5549 |
+
|
5550 |
+
this.el.animate( this.diff, opts );
|
5551 |
+
return dfd.promise();
|
5552 |
+
});
|
5553 |
+
|
5554 |
+
// once all animations have completed:
|
5555 |
+
$.when.apply( $, allAnimations.get() ).done(function() {
|
5556 |
+
|
5557 |
+
// set the final class
|
5558 |
+
applyClassChange();
|
5559 |
+
|
5560 |
+
// for each animated element,
|
5561 |
+
// clear all css properties that were animated
|
5562 |
+
$.each( arguments, function() {
|
5563 |
+
var el = this.el;
|
5564 |
+
$.each( this.diff, function(key) {
|
5565 |
+
el.css( key, "" );
|
5566 |
+
});
|
5567 |
});
|
5568 |
+
|
5569 |
+
// this is guarnteed to be there if you use jQuery.speed()
|
5570 |
+
// it also handles dequeuing the next anim...
|
5571 |
+
o.complete.call( animated[ 0 ] );
|
5572 |
+
});
|
5573 |
+
});
|
5574 |
+
};
|
5575 |
+
|
5576 |
+
$.fn.extend({
|
5577 |
+
addClass: (function( orig ) {
|
5578 |
+
return function( classNames, speed, easing, callback ) {
|
5579 |
+
return speed ?
|
5580 |
+
$.effects.animateClass.call( this,
|
5581 |
+
{ add: classNames }, speed, easing, callback ) :
|
5582 |
+
orig.apply( this, arguments );
|
5583 |
+
};
|
5584 |
+
})( $.fn.addClass ),
|
5585 |
+
|
5586 |
+
removeClass: (function( orig ) {
|
5587 |
+
return function( classNames, speed, easing, callback ) {
|
5588 |
+
return arguments.length > 1 ?
|
5589 |
+
$.effects.animateClass.call( this,
|
5590 |
+
{ remove: classNames }, speed, easing, callback ) :
|
5591 |
+
orig.apply( this, arguments );
|
5592 |
+
};
|
5593 |
+
})( $.fn.removeClass ),
|
5594 |
+
|
5595 |
+
toggleClass: (function( orig ) {
|
5596 |
+
return function( classNames, force, speed, easing, callback ) {
|
5597 |
+
if ( typeof force === "boolean" || force === undefined ) {
|
5598 |
+
if ( !speed ) {
|
5599 |
+
// without speed parameter
|
5600 |
+
return orig.apply( this, arguments );
|
5601 |
+
} else {
|
5602 |
+
return $.effects.animateClass.call( this,
|
5603 |
+
(force ? { add: classNames } : { remove: classNames }),
|
5604 |
+
speed, easing, callback );
|
5605 |
+
}
|
5606 |
+
} else {
|
5607 |
+
// without force parameter
|
5608 |
+
return $.effects.animateClass.call( this,
|
5609 |
+
{ toggle: classNames }, force, speed, easing );
|
5610 |
+
}
|
5611 |
+
};
|
5612 |
+
})( $.fn.toggleClass ),
|
5613 |
+
|
5614 |
+
switchClass: function( remove, add, speed, easing, callback) {
|
5615 |
+
return $.effects.animateClass.call( this, {
|
5616 |
+
add: add,
|
5617 |
+
remove: remove
|
5618 |
+
}, speed, easing, callback );
|
5619 |
}
|
5620 |
});
|
5621 |
|
5622 |
+
})();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5623 |
|
5624 |
+
/******************************************************************************/
|
5625 |
+
/*********************************** EFFECTS **********************************/
|
5626 |
+
/******************************************************************************/
|
5627 |
|
5628 |
+
(function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5629 |
|
5630 |
+
$.extend( $.effects, {
|
5631 |
+
version: "1.10.2",
|
5632 |
|
5633 |
+
// Saves a set of properties in a data storage
|
5634 |
+
save: function( element, set ) {
|
5635 |
+
for( var i=0; i < set.length; i++ ) {
|
5636 |
+
if ( set[ i ] !== null ) {
|
5637 |
+
element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
|
5638 |
+
}
|
5639 |
+
}
|
5640 |
+
},
|
5641 |
|
5642 |
+
// Restores a set of previously saved properties from a data storage
|
5643 |
+
restore: function( element, set ) {
|
5644 |
+
var val, i;
|
5645 |
+
for( i=0; i < set.length; i++ ) {
|
5646 |
+
if ( set[ i ] !== null ) {
|
5647 |
+
val = element.data( dataSpace + set[ i ] );
|
5648 |
+
// support: jQuery 1.6.2
|
5649 |
+
// http://bugs.jquery.com/ticket/9917
|
5650 |
+
// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
|
5651 |
+
// We can't differentiate between "" and 0 here, so we just assume
|
5652 |
+
// empty string since it's likely to be a more common value...
|
5653 |
+
if ( val === undefined ) {
|
5654 |
+
val = "";
|
5655 |
}
|
5656 |
+
element.css( set[ i ], val );
|
5657 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5658 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5659 |
},
|
5660 |
|
5661 |
+
setMode: function( el, mode ) {
|
5662 |
+
if (mode === "toggle") {
|
5663 |
+
mode = el.is( ":hidden" ) ? "show" : "hide";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5664 |
}
|
5665 |
+
return mode;
|
5666 |
},
|
5667 |
|
5668 |
+
// Translates a [top,left] array into a baseline value
|
5669 |
+
// this should be a little more flexible in the future to handle a string & hash
|
5670 |
+
getBaseline: function( origin, original ) {
|
5671 |
+
var y, x;
|
5672 |
+
switch ( origin[ 0 ] ) {
|
5673 |
+
case "top": y = 0; break;
|
5674 |
+
case "middle": y = 0.5; break;
|
5675 |
+
case "bottom": y = 1; break;
|
5676 |
+
default: y = origin[ 0 ] / original.height;
|
5677 |
+
}
|
5678 |
+
switch ( origin[ 1 ] ) {
|
5679 |
+
case "left": x = 0; break;
|
5680 |
+
case "center": x = 0.5; break;
|
5681 |
+
case "right": x = 1; break;
|
5682 |
+
default: x = origin[ 1 ] / original.width;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5683 |
}
|
5684 |
+
return {
|
5685 |
+
x: x,
|
5686 |
+
y: y
|
5687 |
+
};
|
5688 |
},
|
5689 |
|
5690 |
+
// Wraps the element around a wrapper that copies position properties
|
5691 |
+
createWrapper: function( element ) {
|
|
|
|
|
|
|
5692 |
|
5693 |
+
// if the element is already wrapped, return it
|
5694 |
+
if ( element.parent().is( ".ui-effects-wrapper" )) {
|
5695 |
+
return element.parent();
|
5696 |
}
|
5697 |
|
5698 |
+
// wrap the element
|
5699 |
+
var props = {
|
5700 |
+
width: element.outerWidth(true),
|
5701 |
+
height: element.outerHeight(true),
|
5702 |
+
"float": element.css( "float" )
|
5703 |
+
},
|
5704 |
+
wrapper = $( "<div></div>" )
|
5705 |
+
.addClass( "ui-effects-wrapper" )
|
5706 |
+
.css({
|
5707 |
+
fontSize: "100%",
|
5708 |
+
background: "transparent",
|
5709 |
+
border: "none",
|
5710 |
+
margin: 0,
|
5711 |
+
padding: 0
|
5712 |
+
}),
|
5713 |
+
// Store the size in case width/height are defined in % - Fixes #5245
|
5714 |
+
size = {
|
5715 |
+
width: element.width(),
|
5716 |
+
height: element.height()
|
5717 |
+
},
|
5718 |
+
active = document.activeElement;
|
5719 |
+
|
5720 |
+
// support: Firefox
|
5721 |
+
// Firefox incorrectly exposes anonymous content
|
5722 |
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
|
5723 |
+
try {
|
5724 |
+
active.id;
|
5725 |
+
} catch( e ) {
|
5726 |
+
active = document.body;
|
5727 |
}
|
5728 |
|
5729 |
+
element.wrap( wrapper );
|
|
|
5730 |
|
5731 |
+
// Fixes #7595 - Elements lose focus when wrapped.
|
5732 |
+
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
|
5733 |
+
$( active ).focus();
|
5734 |
+
}
|
5735 |
|
5736 |
+
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
|
|
|
5737 |
|
5738 |
+
// transfer positioning properties to the wrapper
|
5739 |
+
if ( element.css( "position" ) === "static" ) {
|
5740 |
+
wrapper.css({ position: "relative" });
|
5741 |
+
element.css({ position: "relative" });
|
|
|
5742 |
} else {
|
5743 |
+
$.extend( props, {
|
5744 |
+
position: element.css( "position" ),
|
5745 |
+
zIndex: element.css( "z-index" )
|
5746 |
+
});
|
5747 |
+
$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
|
5748 |
+
props[ pos ] = element.css( pos );
|
5749 |
+
if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
|
5750 |
+
props[ pos ] = "auto";
|
5751 |
+
}
|
5752 |
+
});
|
5753 |
+
element.css({
|
5754 |
+
position: "relative",
|
5755 |
+
top: 0,
|
5756 |
+
left: 0,
|
5757 |
+
right: "auto",
|
5758 |
+
bottom: "auto"
|
5759 |
+
});
|
|
|
|
|
|
|
5760 |
}
|
5761 |
+
element.css(size);
|
5762 |
|
5763 |
+
return wrapper.css( props ).show();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5764 |
},
|
5765 |
|
5766 |
+
removeWrapper: function( element ) {
|
5767 |
+
var active = document.activeElement;
|
|
|
|
|
|
|
|
|
|
|
|
|
5768 |
|
5769 |
+
if ( element.parent().is( ".ui-effects-wrapper" ) ) {
|
5770 |
+
element.parent().replaceWith( element );
|
|
|
|
|
|
|
|
|
5771 |
|
5772 |
+
// Fixes #7595 - Elements lose focus when wrapped.
|
5773 |
+
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
|
5774 |
+
$( active ).focus();
|
5775 |
+
}
|
5776 |
}
|
|
|
5777 |
|
5778 |
+
|
5779 |
+
return element;
|
|
|
|
|
|
|
|
|
|
|
|
|
5780 |
},
|
5781 |
|
5782 |
+
setTransition: function( element, list, factor, value ) {
|
5783 |
+
value = value || {};
|
5784 |
+
$.each( list, function( i, x ) {
|
5785 |
+
var unit = element.cssUnit( x );
|
5786 |
+
if ( unit[ 0 ] > 0 ) {
|
5787 |
+
value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
|
5788 |
+
}
|
5789 |
});
|
5790 |
+
return value;
|
5791 |
+
}
|
5792 |
+
});
|
5793 |
|
5794 |
+
// return an effect options object for the given parameters:
|
5795 |
+
function _normalizeArguments( effect, options, speed, callback ) {
|
|
|
|
|
|
|
|
|
5796 |
|
5797 |
+
// allow passing all options as the first parameter
|
5798 |
+
if ( $.isPlainObject( effect ) ) {
|
5799 |
+
options = effect;
|
5800 |
+
effect = effect.effect;
|
5801 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5802 |
|
5803 |
+
// convert to an object
|
5804 |
+
effect = { effect: effect };
|
5805 |
+
|
5806 |
+
// catch (effect, null, ...)
|
5807 |
+
if ( options == null ) {
|
5808 |
+
options = {};
|
5809 |
}
|
|
|
5810 |
|
5811 |
+
// catch (effect, callback)
|
5812 |
+
if ( $.isFunction( options ) ) {
|
5813 |
+
callback = options;
|
5814 |
+
speed = null;
|
5815 |
+
options = {};
|
|
|
|
|
|
|
|
|
5816 |
}
|
|
|
5817 |
|
5818 |
+
// catch (effect, speed, ?)
|
5819 |
+
if ( typeof options === "number" || $.fx.speeds[ options ] ) {
|
5820 |
+
callback = speed;
|
5821 |
+
speed = options;
|
5822 |
+
options = {};
|
5823 |
+
}
|
5824 |
|
5825 |
+
// catch (effect, options, callback)
|
5826 |
+
if ( $.isFunction( speed ) ) {
|
5827 |
+
callback = speed;
|
5828 |
+
speed = null;
|
5829 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5830 |
|
5831 |
+
// add options to effect
|
5832 |
+
if ( options ) {
|
5833 |
+
$.extend( effect, options );
|
5834 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5835 |
|
5836 |
+
speed = speed || options.duration;
|
5837 |
+
effect.duration = $.fx.off ? 0 :
|
5838 |
+
typeof speed === "number" ? speed :
|
5839 |
+
speed in $.fx.speeds ? $.fx.speeds[ speed ] :
|
5840 |
+
$.fx.speeds._default;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5841 |
|
5842 |
+
effect.complete = callback || options.complete;
|
|
|
5843 |
|
5844 |
+
return effect;
|
5845 |
+
}
|
|
|
|
|
|
|
|
|
5846 |
|
5847 |
+
function standardAnimationOption( option ) {
|
5848 |
+
// Valid standard speeds (nothing, number, named speed)
|
5849 |
+
if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
|
5850 |
+
return true;
|
5851 |
+
}
|
5852 |
|
5853 |
+
// Invalid strings - treat as "normal" speed
|
5854 |
+
if ( typeof option === "string" && !$.effects.effect[ option ] ) {
|
5855 |
+
return true;
|
5856 |
+
}
|
5857 |
|
5858 |
+
// Complete callback
|
5859 |
+
if ( $.isFunction( option ) ) {
|
5860 |
+
return true;
|
5861 |
+
}
|
5862 |
|
5863 |
+
// Options hash (but not naming an effect)
|
5864 |
+
if ( typeof option === "object" && !option.effect ) {
|
5865 |
+
return true;
|
5866 |
+
}
|
5867 |
|
5868 |
+
// Didn't match any standard API
|
5869 |
+
return false;
|
5870 |
+
}
|
5871 |
+
|
5872 |
+
$.fn.extend({
|
5873 |
+
effect: function( /* effect, options, speed, callback */ ) {
|
5874 |
+
var args = _normalizeArguments.apply( this, arguments ),
|
5875 |
+
mode = args.mode,
|
5876 |
+
queue = args.queue,
|
5877 |
+
effectMethod = $.effects.effect[ args.effect ];
|
5878 |
+
|
5879 |
+
if ( $.fx.off || !effectMethod ) {
|
5880 |
+
// delegate to the original method (e.g., .show()) if possible
|
5881 |
+
if ( mode ) {
|
5882 |
+
return this[ mode ]( args.duration, args.complete );
|
5883 |
+
} else {
|
5884 |
+
return this.each( function() {
|
5885 |
+
if ( args.complete ) {
|
5886 |
+
args.complete.call( this );
|
5887 |
+
}
|
5888 |
+
});
|
5889 |
+
}
|
5890 |
}
|
|
|
5891 |
|
5892 |
+
function run( next ) {
|
5893 |
+
var elem = $( this ),
|
5894 |
+
complete = args.complete,
|
5895 |
+
mode = args.mode;
|
5896 |
+
|
5897 |
+
function done() {
|
5898 |
+
if ( $.isFunction( complete ) ) {
|
5899 |
+
complete.call( elem[0] );
|
5900 |
+
}
|
5901 |
+
if ( $.isFunction( next ) ) {
|
5902 |
+
next();
|
5903 |
+
}
|
5904 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5905 |
|
5906 |
+
// If the element already has the correct final state, delegate to
|
5907 |
+
// the core methods so the internal tracking of "olddisplay" works.
|
5908 |
+
if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
|
5909 |
+
elem[ mode ]();
|
5910 |
+
done();
|
5911 |
+
} else {
|
5912 |
+
effectMethod.call( elem[0], args, done );
|
5913 |
}
|
|
|
|
|
|
|
|
|
5914 |
}
|
5915 |
+
|
5916 |
+
return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
|
5917 |
},
|
5918 |
|
5919 |
+
show: (function( orig ) {
|
5920 |
+
return function( option ) {
|
5921 |
+
if ( standardAnimationOption( option ) ) {
|
5922 |
+
return orig.apply( this, arguments );
|
5923 |
+
} else {
|
5924 |
+
var args = _normalizeArguments.apply( this, arguments );
|
5925 |
+
args.mode = "show";
|
5926 |
+
return this.effect.call( this, args );
|
5927 |
}
|
5928 |
+
};
|
5929 |
+
})( $.fn.show ),
|
5930 |
|
5931 |
+
hide: (function( orig ) {
|
5932 |
+
return function( option ) {
|
5933 |
+
if ( standardAnimationOption( option ) ) {
|
5934 |
+
return orig.apply( this, arguments );
|
5935 |
+
} else {
|
5936 |
+
var args = _normalizeArguments.apply( this, arguments );
|
5937 |
+
args.mode = "hide";
|
5938 |
+
return this.effect.call( this, args );
|
5939 |
+
}
|
5940 |
+
};
|
5941 |
+
})( $.fn.hide ),
|
5942 |
|
5943 |
+
toggle: (function( orig ) {
|
5944 |
+
return function( option ) {
|
5945 |
+
if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
|
5946 |
+
return orig.apply( this, arguments );
|
5947 |
+
} else {
|
5948 |
+
var args = _normalizeArguments.apply( this, arguments );
|
5949 |
+
args.mode = "toggle";
|
5950 |
+
return this.effect.call( this, args );
|
5951 |
}
|
5952 |
+
};
|
5953 |
+
})( $.fn.toggle ),
|
|
|
|
|
|
|
|
|
5954 |
|
5955 |
+
// helper functions
|
5956 |
+
cssUnit: function(key) {
|
5957 |
+
var style = this.css( key ),
|
5958 |
+
val = [];
|
5959 |
|
5960 |
+
$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
|
5961 |
+
if ( style.indexOf( unit ) > 0 ) {
|
5962 |
+
val = [ parseFloat( style ), unit ];
|
5963 |
+
}
|
5964 |
+
});
|
5965 |
+
return val;
|
5966 |
}
|
5967 |
});
|
5968 |
|
5969 |
+
})();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5970 |
|
5971 |
+
/******************************************************************************/
|
5972 |
+
/*********************************** EASING ***********************************/
|
5973 |
+
/******************************************************************************/
|
5974 |
+
|
5975 |
+
(function() {
|
5976 |
+
|
5977 |
+
// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
|
5978 |
+
|
5979 |
+
var baseEasings = {};
|
5980 |
+
|
5981 |
+
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
|
5982 |
+
baseEasings[ name ] = function( p ) {
|
5983 |
+
return Math.pow( p, i + 2 );
|
5984 |
+
};
|
5985 |
+
});
|
5986 |
+
|
5987 |
+
$.extend( baseEasings, {
|
5988 |
+
Sine: function ( p ) {
|
5989 |
+
return 1 - Math.cos( p * Math.PI / 2 );
|
5990 |
},
|
5991 |
+
Circ: function ( p ) {
|
5992 |
+
return 1 - Math.sqrt( 1 - p * p );
|
5993 |
+
},
|
5994 |
+
Elastic: function( p ) {
|
5995 |
+
return p === 0 || p === 1 ? p :
|
5996 |
+
-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
|
5997 |
+
},
|
5998 |
+
Back: function( p ) {
|
5999 |
+
return p * p * ( 3 * p - 2 );
|
6000 |
+
},
|
6001 |
+
Bounce: function ( p ) {
|
6002 |
+
var pow2,
|
6003 |
+
bounce = 4;
|
6004 |
+
|
6005 |
+
while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
|
6006 |
+
return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
|
6007 |
+
}
|
6008 |
+
});
|
6009 |
+
|
6010 |
+
$.each( baseEasings, function( name, easeIn ) {
|
6011 |
+
$.easing[ "easeIn" + name ] = easeIn;
|
6012 |
+
$.easing[ "easeOut" + name ] = function( p ) {
|
6013 |
+
return 1 - easeIn( 1 - p );
|
6014 |
+
};
|
6015 |
+
$.easing[ "easeInOut" + name ] = function( p ) {
|
6016 |
+
return p < 0.5 ?
|
6017 |
+
easeIn( p * 2 ) / 2 :
|
6018 |
+
1 - easeIn( p * -2 + 2 ) / 2;
|
6019 |
};
|
6020 |
+
});
|
6021 |
|
6022 |
+
})();
|
6023 |
+
|
6024 |
+
})(jQuery);
|
6025 |
+
|
6026 |
+
(function( $, undefined ) {
|
6027 |
+
|
6028 |
+
var uid = 0,
|
6029 |
+
hideProps = {},
|
6030 |
+
showProps = {};
|
6031 |
+
|
6032 |
+
hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
|
6033 |
+
hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
|
6034 |
+
showProps.height = showProps.paddingTop = showProps.paddingBottom =
|
6035 |
+
showProps.borderTopWidth = showProps.borderBottomWidth = "show";
|
6036 |
+
|
6037 |
+
$.widget( "ui.accordion", {
|
6038 |
+
version: "1.10.2",
|
6039 |
options: {
|
6040 |
+
active: 0,
|
6041 |
+
animate: {},
|
6042 |
+
collapsible: false,
|
6043 |
+
event: "click",
|
6044 |
+
header: "> li > :first-child,> :not(li):even",
|
6045 |
+
heightStyle: "auto",
|
6046 |
icons: {
|
6047 |
+
activeHeader: "ui-icon-triangle-1-s",
|
6048 |
+
header: "ui-icon-triangle-1-e"
|
6049 |
+
},
|
6050 |
+
|
6051 |
+
// callbacks
|
6052 |
+
activate: null,
|
6053 |
+
beforeActivate: null
|
6054 |
},
|
6055 |
+
|
6056 |
_create: function() {
|
6057 |
+
var options = this.options;
|
6058 |
+
this.prevShow = this.prevHide = $();
|
6059 |
+
this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
|
6060 |
+
// ARIA
|
6061 |
+
.attr( "role", "tablist" );
|
6062 |
|
6063 |
+
// don't allow collapsible: false and active: false / null
|
6064 |
+
if ( !options.collapsible && (options.active === false || options.active == null) ) {
|
6065 |
+
options.active = 0;
|
6066 |
}
|
6067 |
|
6068 |
+
this._processPanels();
|
6069 |
+
// handle negative values
|
6070 |
+
if ( options.active < 0 ) {
|
6071 |
+
options.active += this.headers.length;
|
6072 |
+
}
|
6073 |
+
this._refresh();
|
6074 |
+
},
|
6075 |
|
6076 |
+
_getCreateEventData: function() {
|
6077 |
+
return {
|
6078 |
+
header: this.active,
|
6079 |
+
panel: !this.active.length ? $() : this.active.next(),
|
6080 |
+
content: !this.active.length ? $() : this.active.next()
|
6081 |
+
};
|
6082 |
+
},
|
6083 |
|
6084 |
+
_createIcons: function() {
|
6085 |
+
var icons = this.options.icons;
|
6086 |
+
if ( icons ) {
|
6087 |
+
$( "<span>" )
|
6088 |
+
.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
|
6089 |
+
.prependTo( this.headers );
|
6090 |
+
this.active.children( ".ui-accordion-header-icon" )
|
6091 |
+
.removeClass( icons.header )
|
6092 |
+
.addClass( icons.activeHeader );
|
6093 |
+
this.headers.addClass( "ui-accordion-icons" );
|
6094 |
}
|
6095 |
+
},
|
6096 |
|
6097 |
+
_destroyIcons: function() {
|
6098 |
+
this.headers
|
6099 |
+
.removeClass( "ui-accordion-icons" )
|
6100 |
+
.children( ".ui-accordion-header-icon" )
|
6101 |
+
.remove();
|
6102 |
+
},
|
6103 |
|
6104 |
+
_destroy: function() {
|
6105 |
+
var contents;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6106 |
|
6107 |
+
// clean up main element
|
6108 |
this.element
|
6109 |
+
.removeClass( "ui-accordion ui-widget ui-helper-reset" )
|
6110 |
+
.removeAttr( "role" );
|
|
|
|
|
|
|
|
|
|
|
6111 |
|
6112 |
+
// clean up headers
|
6113 |
+
this.headers
|
6114 |
+
.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" )
|
6115 |
+
.removeAttr( "role" )
|
6116 |
+
.removeAttr( "aria-selected" )
|
6117 |
+
.removeAttr( "aria-controls" )
|
6118 |
+
.removeAttr( "tabIndex" )
|
6119 |
+
.each(function() {
|
6120 |
+
if ( /^ui-accordion/.test( this.id ) ) {
|
6121 |
+
this.removeAttribute( "id" );
|
6122 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6123 |
});
|
6124 |
+
this._destroyIcons();
|
6125 |
|
6126 |
+
// clean up content panels
|
6127 |
+
contents = this.headers.next()
|
6128 |
+
.css( "display", "" )
|
6129 |
+
.removeAttr( "role" )
|
6130 |
+
.removeAttr( "aria-expanded" )
|
6131 |
+
.removeAttr( "aria-hidden" )
|
6132 |
+
.removeAttr( "aria-labelledby" )
|
6133 |
+
.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
|
6134 |
+
.each(function() {
|
6135 |
+
if ( /^ui-accordion/.test( this.id ) ) {
|
6136 |
+
this.removeAttribute( "id" );
|
6137 |
}
|
|
|
|
|
6138 |
});
|
6139 |
+
if ( this.options.heightStyle !== "content" ) {
|
6140 |
+
contents.css( "height", "" );
|
6141 |
+
}
|
6142 |
+
},
|
|
|
|
|
|
|
6143 |
|
6144 |
+
_setOption: function( key, value ) {
|
6145 |
+
if ( key === "active" ) {
|
6146 |
+
// _activate() will handle invalid values and update this.options
|
6147 |
+
this._activate( value );
|
6148 |
+
return;
|
6149 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6150 |
|
6151 |
+
if ( key === "event" ) {
|
6152 |
+
if ( this.options.event ) {
|
6153 |
+
this._off( this.headers, this.options.event );
|
|
|
|
|
|
|
|
|
6154 |
}
|
6155 |
+
this._setupEvents( value );
|
6156 |
}
|
6157 |
|
6158 |
+
this._super( key, value );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6159 |
|
6160 |
+
// setting collapsible: false while collapsed; open first panel
|
6161 |
+
if ( key === "collapsible" && !value && this.options.active === false ) {
|
6162 |
+
this._activate( 0 );
|
|
|
|
|
|
|
|
|
|
|
6163 |
}
|
6164 |
|
6165 |
+
if ( key === "icons" ) {
|
6166 |
+
this._destroyIcons();
|
6167 |
+
if ( value ) {
|
6168 |
+
this._createIcons();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6169 |
}
|
6170 |
+
}
|
6171 |
|
6172 |
+
// #5332 - opacity doesn't cascade to positioned elements in IE
|
6173 |
+
// so we need to add the disabled class to the headers and panels
|
6174 |
+
if ( key === "disabled" ) {
|
6175 |
+
this.headers.add( this.headers.next() )
|
6176 |
+
.toggleClass( "ui-state-disabled", !!value );
|
|
|
|
|
6177 |
}
|
6178 |
},
|
6179 |
|
6180 |
+
_keydown: function( event ) {
|
6181 |
+
/*jshint maxcomplexity:15*/
|
6182 |
+
if ( event.altKey || event.ctrlKey ) {
|
6183 |
+
return;
|
6184 |
+
}
|
6185 |
|
6186 |
+
var keyCode = $.ui.keyCode,
|
6187 |
+
length = this.headers.length,
|
6188 |
+
currentIndex = this.headers.index( event.target ),
|
6189 |
+
toFocus = false;
|
|
|
|
|
|
|
|
|
6190 |
|
6191 |
+
switch ( event.keyCode ) {
|
6192 |
+
case keyCode.RIGHT:
|
6193 |
+
case keyCode.DOWN:
|
6194 |
+
toFocus = this.headers[ ( currentIndex + 1 ) % length ];
|
6195 |
+
break;
|
6196 |
+
case keyCode.LEFT:
|
6197 |
+
case keyCode.UP:
|
6198 |
+
toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
|
6199 |
+
break;
|
6200 |
+
case keyCode.SPACE:
|
6201 |
+
case keyCode.ENTER:
|
6202 |
+
this._eventHandler( event );
|
6203 |
+
break;
|
6204 |
+
case keyCode.HOME:
|
6205 |
+
toFocus = this.headers[ 0 ];
|
6206 |
+
break;
|
6207 |
+
case keyCode.END:
|
6208 |
+
toFocus = this.headers[ length - 1 ];
|
6209 |
+
break;
|
6210 |
}
|
6211 |
|
6212 |
+
if ( toFocus ) {
|
6213 |
+
$( event.target ).attr( "tabIndex", -1 );
|
6214 |
+
$( toFocus ).attr( "tabIndex", 0 );
|
6215 |
+
toFocus.focus();
|
6216 |
+
event.preventDefault();
|
6217 |
+
}
|
6218 |
},
|
6219 |
|
6220 |
+
_panelKeyDown : function( event ) {
|
6221 |
+
if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
|
6222 |
+
$( event.currentTarget ).prev().focus();
|
|
|
|
|
|
|
|
|
|
|
|
|
6223 |
}
|
|
|
6224 |
},
|
6225 |
|
6226 |
refresh: function() {
|
6227 |
+
var options = this.options;
|
6228 |
+
this._processPanels();
|
6229 |
+
|
6230 |
+
// was collapsed or no panel
|
6231 |
+
if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
|
6232 |
+
options.active = false;
|
6233 |
+
this.active = $();
|
6234 |
+
// active false only when collapsible is true
|
6235 |
+
} if ( options.active === false ) {
|
6236 |
+
this._activate( 0 );
|
6237 |
+
// was active, but active panel is gone
|
6238 |
+
} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
|
6239 |
+
// all remaining panel are disabled
|
6240 |
+
if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
|
6241 |
+
options.active = false;
|
6242 |
+
this.active = $();
|
6243 |
+
// activate previous panel
|
|
|
|
|
|
|
|
|
6244 |
} else {
|
6245 |
+
this._activate( Math.max( 0, options.active - 1 ) );
|
|
|
|
|
6246 |
}
|
6247 |
+
// was active, active panel still exists
|
6248 |
+
} else {
|
6249 |
+
// make sure active index is correct
|
6250 |
+
options.active = this.headers.index( this.active );
|
6251 |
}
|
|
|
6252 |
|
6253 |
+
this._destroyIcons();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6254 |
|
6255 |
+
this._refresh();
|
6256 |
+
},
|
|
|
|
|
6257 |
|
6258 |
+
_processPanels: function() {
|
6259 |
+
this.headers = this.element.find( this.options.header )
|
6260 |
+
.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
|
6261 |
|
6262 |
+
this.headers.next()
|
6263 |
+
.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
|
6264 |
+
.filter(":not(.ui-accordion-content-active)")
|
6265 |
+
.hide();
|
6266 |
+
},
|
6267 |
|
6268 |
+
_refresh: function() {
|
6269 |
+
var maxHeight,
|
6270 |
+
options = this.options,
|
6271 |
+
heightStyle = options.heightStyle,
|
6272 |
+
parent = this.element.parent(),
|
6273 |
+
accordionId = this.accordionId = "ui-accordion-" +
|
6274 |
+
(this.element.attr( "id" ) || ++uid);
|
6275 |
+
|
6276 |
+
this.active = this._findActive( options.active )
|
6277 |
+
.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
|
6278 |
+
.removeClass( "ui-corner-all" );
|
6279 |
+
this.active.next()
|
6280 |
+
.addClass( "ui-accordion-content-active" )
|
6281 |
+
.show();
|
6282 |
|
6283 |
+
this.headers
|
6284 |
+
.attr( "role", "tab" )
|
6285 |
+
.each(function( i ) {
|
6286 |
+
var header = $( this ),
|
6287 |
+
headerId = header.attr( "id" ),
|
6288 |
+
panel = header.next(),
|
6289 |
+
panelId = panel.attr( "id" );
|
6290 |
+
if ( !headerId ) {
|
6291 |
+
headerId = accordionId + "-header-" + i;
|
6292 |
+
header.attr( "id", headerId );
|
6293 |
}
|
6294 |
+
if ( !panelId ) {
|
6295 |
+
panelId = accordionId + "-panel-" + i;
|
6296 |
+
panel.attr( "id", panelId );
|
6297 |
+
}
|
6298 |
+
header.attr( "aria-controls", panelId );
|
6299 |
+
panel.attr( "aria-labelledby", headerId );
|
6300 |
+
})
|
6301 |
+
.next()
|
6302 |
+
.attr( "role", "tabpanel" );
|
6303 |
+
|
6304 |
+
this.headers
|
6305 |
+
.not( this.active )
|
6306 |
+
.attr({
|
6307 |
+
"aria-selected": "false",
|
6308 |
+
tabIndex: -1
|
6309 |
+
})
|
6310 |
+
.next()
|
6311 |
+
.attr({
|
6312 |
+
"aria-expanded": "false",
|
6313 |
+
"aria-hidden": "true"
|
6314 |
+
})
|
6315 |
+
.hide();
|
6316 |
+
|
6317 |
+
// make sure at least one header is in the tab order
|
6318 |
+
if ( !this.active.length ) {
|
6319 |
+
this.headers.eq( 0 ).attr( "tabIndex", 0 );
|
6320 |
} else {
|
6321 |
+
this.active.attr({
|
6322 |
+
"aria-selected": "true",
|
6323 |
+
tabIndex: 0
|
6324 |
+
})
|
6325 |
+
.next()
|
6326 |
+
.attr({
|
6327 |
+
"aria-expanded": "true",
|
6328 |
+
"aria-hidden": "false"
|
6329 |
+
});
|
6330 |
}
|
|
|
|
|
|
|
6331 |
|
6332 |
+
this._createIcons();
|
6333 |
+
|
6334 |
+
this._setupEvents( options.event );
|
6335 |
+
|
6336 |
+
if ( heightStyle === "fill" ) {
|
6337 |
+
maxHeight = parent.height();
|
6338 |
+
this.element.siblings( ":visible" ).each(function() {
|
6339 |
+
var elem = $( this ),
|
6340 |
+
position = elem.css( "position" );
|
6341 |
+
|
6342 |
+
if ( position === "absolute" || position === "fixed" ) {
|
6343 |
+
return;
|
6344 |
+
}
|
6345 |
+
maxHeight -= elem.outerHeight( true );
|
6346 |
+
});
|
6347 |
+
|
6348 |
+
this.headers.each(function() {
|
6349 |
+
maxHeight -= $( this ).outerHeight( true );
|
6350 |
+
});
|
6351 |
+
|
6352 |
+
this.headers.next()
|
6353 |
+
.each(function() {
|
6354 |
+
$( this ).height( Math.max( 0, maxHeight -
|
6355 |
+
$( this ).innerHeight() + $( this ).height() ) );
|
6356 |
+
})
|
6357 |
+
.css( "overflow", "auto" );
|
6358 |
+
} else if ( heightStyle === "auto" ) {
|
6359 |
+
maxHeight = 0;
|
6360 |
+
this.headers.next()
|
6361 |
+
.each(function() {
|
6362 |
+
maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
|
6363 |
+
})
|
6364 |
+
.height( maxHeight );
|
6365 |
+
}
|
6366 |
},
|
6367 |
|
6368 |
+
_activate: function( index ) {
|
6369 |
+
var active = this._findActive( index )[ 0 ];
|
6370 |
+
|
6371 |
+
// trying to activate the already active panel
|
6372 |
+
if ( active === this.active[ 0 ] ) {
|
6373 |
+
return;
|
6374 |
+
}
|
6375 |
+
|
6376 |
+
// trying to collapse, simulate a click on the currently active header
|
6377 |
+
active = active || this.active[ 0 ];
|
6378 |
+
|
6379 |
+
this._eventHandler({
|
6380 |
+
target: active,
|
6381 |
+
currentTarget: active,
|
6382 |
+
preventDefault: $.noop
|
6383 |
+
});
|
6384 |
},
|
6385 |
+
|
6386 |
+
_findActive: function( selector ) {
|
6387 |
+
return typeof selector === "number" ? this.headers.eq( selector ) : $();
|
6388 |
},
|
6389 |
|
6390 |
+
_setupEvents: function( event ) {
|
6391 |
+
var events = {
|
6392 |
+
keydown: "_keydown"
|
6393 |
+
};
|
6394 |
+
if ( event ) {
|
6395 |
+
$.each( event.split(" "), function( index, eventName ) {
|
6396 |
+
events[ eventName ] = "_eventHandler";
|
6397 |
+
});
|
6398 |
}
|
6399 |
|
6400 |
+
this._off( this.headers.add( this.headers.next() ) );
|
6401 |
+
this._on( this.headers, events );
|
6402 |
+
this._on( this.headers.next(), { keydown: "_panelKeyDown" });
|
6403 |
+
this._hoverable( this.headers );
|
6404 |
+
this._focusable( this.headers );
|
6405 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6406 |
|
6407 |
+
_eventHandler: function( event ) {
|
6408 |
+
var options = this.options,
|
6409 |
+
active = this.active,
|
6410 |
+
clicked = $( event.currentTarget ),
|
6411 |
+
clickedIsActive = clicked[ 0 ] === active[ 0 ],
|
6412 |
+
collapsing = clickedIsActive && options.collapsible,
|
6413 |
+
toShow = collapsing ? $() : clicked.next(),
|
6414 |
+
toHide = active.next(),
|
6415 |
+
eventData = {
|
6416 |
+
oldHeader: active,
|
6417 |
+
oldPanel: toHide,
|
6418 |
+
newHeader: collapsing ? $() : clicked,
|
6419 |
+
newPanel: toShow
|
6420 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6421 |
|
6422 |
+
event.preventDefault();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6423 |
|
6424 |
+
if (
|
6425 |
+
// click on active header, but not collapsible
|
6426 |
+
( clickedIsActive && !options.collapsible ) ||
|
6427 |
+
// allow canceling activation
|
6428 |
+
( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
|
6429 |
+
return;
|
6430 |
}
|
6431 |
|
6432 |
+
options.active = collapsing ? false : this.headers.index( clicked );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6433 |
|
6434 |
+
// when the call to ._toggle() comes after the class changes
|
6435 |
+
// it causes a very odd bug in IE 8 (see #6720)
|
6436 |
+
this.active = clickedIsActive ? $() : clicked;
|
6437 |
+
this._toggle( eventData );
|
6438 |
|
6439 |
+
// switch classes
|
6440 |
+
// corner classes on the previously active header stay after the animation
|
6441 |
+
active.removeClass( "ui-accordion-header-active ui-state-active" );
|
6442 |
+
if ( options.icons ) {
|
6443 |
+
active.children( ".ui-accordion-header-icon" )
|
6444 |
+
.removeClass( options.icons.activeHeader )
|
6445 |
+
.addClass( options.icons.header );
|
6446 |
}
|
6447 |
|
6448 |
+
if ( !clickedIsActive ) {
|
6449 |
+
clicked
|
6450 |
+
.removeClass( "ui-corner-all" )
|
6451 |
+
.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
|
6452 |
+
if ( options.icons ) {
|
6453 |
+
clicked.children( ".ui-accordion-header-icon" )
|
6454 |
+
.removeClass( options.icons.header )
|
6455 |
+
.addClass( options.icons.activeHeader );
|
6456 |
+
}
|
6457 |
|
6458 |
+
clicked
|
6459 |
+
.next()
|
6460 |
+
.addClass( "ui-accordion-content-active" );
|
6461 |
}
|
6462 |
},
|
6463 |
|
6464 |
+
_toggle: function( data ) {
|
6465 |
+
var toShow = data.newPanel,
|
6466 |
+
toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
|
|
|
|
|
6467 |
|
6468 |
+
// handle activating a panel during the animation for another activation
|
6469 |
+
this.prevShow.add( this.prevHide ).stop( true, true );
|
6470 |
+
this.prevShow = toShow;
|
6471 |
+
this.prevHide = toHide;
|
6472 |
+
|
6473 |
+
if ( this.options.animate ) {
|
6474 |
+
this._animate( toShow, toHide, data );
|
6475 |
+
} else {
|
6476 |
+
toHide.hide();
|
6477 |
+
toShow.show();
|
6478 |
+
this._toggleComplete( data );
|
6479 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6480 |
|
6481 |
+
toHide.attr({
|
6482 |
+
"aria-expanded": "false",
|
6483 |
+
"aria-hidden": "true"
|
6484 |
+
});
|
6485 |
+
toHide.prev().attr( "aria-selected", "false" );
|
6486 |
+
// if we're switching panels, remove the old header from the tab order
|
6487 |
+
// if we're opening from collapsed state, remove the previous header from the tab order
|
6488 |
+
// if we're collapsing, then keep the collapsing header in the tab order
|
6489 |
+
if ( toShow.length && toHide.length ) {
|
6490 |
+
toHide.prev().attr( "tabIndex", -1 );
|
6491 |
+
} else if ( toShow.length ) {
|
6492 |
+
this.headers.filter(function() {
|
6493 |
+
return $( this ).attr( "tabIndex" ) === 0;
|
6494 |
+
})
|
6495 |
+
.attr( "tabIndex", -1 );
|
6496 |
}
|
6497 |
|
6498 |
+
toShow
|
6499 |
+
.attr({
|
6500 |
+
"aria-expanded": "true",
|
6501 |
+
"aria-hidden": "false"
|
6502 |
+
})
|
6503 |
+
.prev()
|
6504 |
+
.attr({
|
6505 |
+
"aria-selected": "true",
|
6506 |
+
tabIndex: 0
|
6507 |
+
});
|
6508 |
},
|
6509 |
|
6510 |
+
_animate: function( toShow, toHide, data ) {
|
6511 |
+
var total, easing, duration,
|
6512 |
+
that = this,
|
6513 |
+
adjust = 0,
|
6514 |
+
down = toShow.length &&
|
6515 |
+
( !toHide.length || ( toShow.index() < toHide.index() ) ),
|
6516 |
+
animate = this.options.animate || {},
|
6517 |
+
options = down && animate.down || animate,
|
6518 |
+
complete = function() {
|
6519 |
+
that._toggleComplete( data );
|
6520 |
+
};
|
6521 |
|
6522 |
+
if ( typeof options === "number" ) {
|
6523 |
+
duration = options;
|
|
|
|
|
|
|
|
|
6524 |
}
|
6525 |
+
if ( typeof options === "string" ) {
|
6526 |
+
easing = options;
|
|
|
6527 |
}
|
6528 |
+
// fall back from options to animation in case of partial down settings
|
6529 |
+
easing = easing || options.easing || animate.easing;
|
6530 |
+
duration = duration || options.duration || animate.duration;
|
6531 |
|
6532 |
+
if ( !toHide.length ) {
|
6533 |
+
return toShow.animate( showProps, duration, easing, complete );
|
6534 |
+
}
|
6535 |
+
if ( !toShow.length ) {
|
6536 |
+
return toHide.animate( hideProps, duration, easing, complete );
|
|
|
|
|
|
|
|
|
6537 |
}
|
6538 |
|
6539 |
+
total = toShow.show().outerHeight();
|
6540 |
+
toHide.animate( hideProps, {
|
6541 |
+
duration: duration,
|
6542 |
+
easing: easing,
|
6543 |
+
step: function( now, fx ) {
|
6544 |
+
fx.now = Math.round( now );
|
6545 |
+
}
|
6546 |
+
});
|
6547 |
+
toShow
|
6548 |
+
.hide()
|
6549 |
+
.animate( showProps, {
|
6550 |
+
duration: duration,
|
6551 |
+
easing: easing,
|
6552 |
+
complete: complete,
|
6553 |
+
step: function( now, fx ) {
|
6554 |
+
fx.now = Math.round( now );
|
6555 |
+
if ( fx.prop !== "height" ) {
|
6556 |
+
adjust += fx.now;
|
6557 |
+
} else if ( that.options.heightStyle !== "content" ) {
|
6558 |
+
fx.now = Math.round( total - toHide.outerHeight() - adjust );
|
6559 |
+
adjust = 0;
|
6560 |
}
|
6561 |
}
|
6562 |
});
|
|
|
|
|
|
|
|
|
6563 |
},
|
6564 |
|
6565 |
+
_toggleComplete: function( data ) {
|
6566 |
+
var toHide = data.oldPanel;
|
|
|
6567 |
|
6568 |
+
toHide
|
6569 |
+
.removeClass( "ui-accordion-content-active" )
|
6570 |
+
.prev()
|
6571 |
+
.removeClass( "ui-corner-top" )
|
6572 |
+
.addClass( "ui-corner-all" );
|
|
|
6573 |
|
6574 |
+
// Work around for rendering bug in IE (#5421)
|
6575 |
+
if ( toHide.length ) {
|
6576 |
+
toHide.parent()[0].className = toHide.parent()[0].className;
|
6577 |
}
|
6578 |
|
6579 |
+
this._trigger( "activate", null, data );
|
6580 |
+
}
|
6581 |
+
});
|
|
|
|
|
|
|
|
|
6582 |
|
6583 |
+
})( jQuery );
|
|
|
|
|
|
|
|
|
|
|
|
|
6584 |
|
6585 |
+
(function( $, undefined ) {
|
|
|
6586 |
|
6587 |
+
// used to prevent race conditions with remote data sources
|
6588 |
+
var requestIndex = 0;
|
6589 |
+
|
6590 |
+
$.widget( "ui.autocomplete", {
|
6591 |
+
version: "1.10.2",
|
6592 |
+
defaultElement: "<input>",
|
6593 |
+
options: {
|
6594 |
+
appendTo: null,
|
6595 |
+
autoFocus: false,
|
6596 |
+
delay: 300,
|
6597 |
+
minLength: 1,
|
6598 |
+
position: {
|
6599 |
+
my: "left top",
|
6600 |
+
at: "left bottom",
|
6601 |
+
collision: "none"
|
6602 |
+
},
|
6603 |
+
source: null,
|
6604 |
|
6605 |
+
// callbacks
|
6606 |
+
change: null,
|
6607 |
+
close: null,
|
6608 |
+
focus: null,
|
6609 |
+
open: null,
|
6610 |
+
response: null,
|
6611 |
+
search: null,
|
6612 |
+
select: null
|
6613 |
+
},
|
6614 |
|
6615 |
+
pending: 0,
|
|
|
|
|
|
|
|
|
6616 |
|
6617 |
+
_create: function() {
|
6618 |
+
// Some browsers only repeat keydown events, not keypress events,
|
6619 |
+
// so we use the suppressKeyPress flag to determine if we've already
|
6620 |
+
// handled the keydown event. #7269
|
6621 |
+
// Unfortunately the code for & in keypress is the same as the up arrow,
|
6622 |
+
// so we use the suppressKeyPressRepeat flag to avoid handling keypress
|
6623 |
+
// events when we know the keydown event was used to modify the
|
6624 |
+
// search term. #7799
|
6625 |
+
var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
|
6626 |
+
nodeName = this.element[0].nodeName.toLowerCase(),
|
6627 |
+
isTextarea = nodeName === "textarea",
|
6628 |
+
isInput = nodeName === "input";
|
6629 |
+
|
6630 |
+
this.isMultiLine =
|
6631 |
+
// Textareas are always multi-line
|
6632 |
+
isTextarea ? true :
|
6633 |
+
// Inputs are always single-line, even if inside a contentEditable element
|
6634 |
+
// IE also treats inputs as contentEditable
|
6635 |
+
isInput ? false :
|
6636 |
+
// All other element types are determined by whether or not they're contentEditable
|
6637 |
+
this.element.prop( "isContentEditable" );
|
6638 |
+
|
6639 |
+
this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
|
6640 |
+
this.isNewMenu = true;
|
6641 |
+
|
6642 |
+
this.element
|
6643 |
+
.addClass( "ui-autocomplete-input" )
|
6644 |
+
.attr( "autocomplete", "off" );
|
6645 |
+
|
6646 |
+
this._on( this.element, {
|
6647 |
+
keydown: function( event ) {
|
6648 |
+
/*jshint maxcomplexity:15*/
|
6649 |
+
if ( this.element.prop( "readOnly" ) ) {
|
6650 |
+
suppressKeyPress = true;
|
6651 |
+
suppressInput = true;
|
6652 |
+
suppressKeyPressRepeat = true;
|
6653 |
return;
|
6654 |
}
|
6655 |
|
6656 |
+
suppressKeyPress = false;
|
6657 |
+
suppressInput = false;
|
6658 |
+
suppressKeyPressRepeat = false;
|
6659 |
+
var keyCode = $.ui.keyCode;
|
6660 |
+
switch( event.keyCode ) {
|
6661 |
+
case keyCode.PAGE_UP:
|
6662 |
+
suppressKeyPress = true;
|
6663 |
+
this._move( "previousPage", event );
|
6664 |
+
break;
|
6665 |
+
case keyCode.PAGE_DOWN:
|
6666 |
+
suppressKeyPress = true;
|
6667 |
+
this._move( "nextPage", event );
|
6668 |
+
break;
|
6669 |
+
case keyCode.UP:
|
6670 |
+
suppressKeyPress = true;
|
6671 |
+
this._keyEvent( "previous", event );
|
6672 |
+
break;
|
6673 |
+
case keyCode.DOWN:
|
6674 |
+
suppressKeyPress = true;
|
6675 |
+
this._keyEvent( "next", event );
|
6676 |
+
break;
|
6677 |
+
case keyCode.ENTER:
|
6678 |
+
case keyCode.NUMPAD_ENTER:
|
6679 |
+
// when menu is open and has focus
|
6680 |
+
if ( this.menu.active ) {
|
6681 |
+
// #6055 - Opera still allows the keypress to occur
|
6682 |
+
// which causes forms to submit
|
6683 |
+
suppressKeyPress = true;
|
6684 |
+
event.preventDefault();
|
6685 |
+
this.menu.select( event );
|
6686 |
+
}
|
6687 |
+
break;
|
6688 |
+
case keyCode.TAB:
|
6689 |
+
if ( this.menu.active ) {
|
6690 |
+
this.menu.select( event );
|
6691 |
+
}
|
6692 |
+
break;
|
6693 |
+
case keyCode.ESCAPE:
|
6694 |
+
if ( this.menu.element.is( ":visible" ) ) {
|
6695 |
+
this._value( this.term );
|
6696 |
+
this.close( event );
|
6697 |
+
// Different browsers have different default behavior for escape
|
6698 |
+
// Single press can mean undo or clear
|
6699 |
+
// Double press in IE means clear the whole form
|
6700 |
+
event.preventDefault();
|
6701 |
+
}
|
6702 |
+
break;
|
6703 |
+
default:
|
6704 |
+
suppressKeyPressRepeat = true;
|
6705 |
+
// search timeout should be triggered before the input value is changed
|
6706 |
+
this._searchTimeout( event );
|
6707 |
+
break;
|
6708 |
+
}
|
6709 |
+
},
|
6710 |
+
keypress: function( event ) {
|
6711 |
+
if ( suppressKeyPress ) {
|
6712 |
+
suppressKeyPress = false;
|
6713 |
+
event.preventDefault();
|
6714 |
+
return;
|
6715 |
+
}
|
6716 |
+
if ( suppressKeyPressRepeat ) {
|
6717 |
+
return;
|
6718 |
}
|
|
|
|
|
6719 |
|
6720 |
+
// replicate some key handlers to allow them to repeat in Firefox and Opera
|
6721 |
+
var keyCode = $.ui.keyCode;
|
6722 |
+
switch( event.keyCode ) {
|
6723 |
+
case keyCode.PAGE_UP:
|
6724 |
+
this._move( "previousPage", event );
|
6725 |
+
break;
|
6726 |
+
case keyCode.PAGE_DOWN:
|
6727 |
+
this._move( "nextPage", event );
|
6728 |
+
break;
|
6729 |
+
case keyCode.UP:
|
6730 |
+
this._keyEvent( "previous", event );
|
6731 |
+
break;
|
6732 |
+
case keyCode.DOWN:
|
6733 |
+
this._keyEvent( "next", event );
|
6734 |
+
break;
|
6735 |
+
}
|
6736 |
+
},
|
6737 |
+
input: function( event ) {
|
6738 |
+
if ( suppressInput ) {
|
6739 |
+
suppressInput = false;
|
6740 |
+
event.preventDefault();
|
6741 |
+
return;
|
6742 |
+
}
|
6743 |
+
this._searchTimeout( event );
|
6744 |
+
},
|
6745 |
+
focus: function() {
|
6746 |
+
this.selectedItem = null;
|
6747 |
+
this.previous = this._value();
|
6748 |
+
},
|
6749 |
+
blur: function( event ) {
|
6750 |
+
if ( this.cancelBlur ) {
|
6751 |
+
delete this.cancelBlur;
|
6752 |
+
return;
|
6753 |
+
}
|
6754 |
|
6755 |
+
clearTimeout( this.searching );
|
6756 |
+
this.close( event );
|
6757 |
+
this._change( event );
|
6758 |
+
}
|
6759 |
+
});
|
6760 |
|
6761 |
+
this._initSource();
|
6762 |
+
this.menu = $( "<ul>" )
|
6763 |
+
.addClass( "ui-autocomplete ui-front" )
|
6764 |
+
.appendTo( this._appendTo() )
|
6765 |
+
.menu({
|
6766 |
+
// custom key handling for now
|
6767 |
+
input: $(),
|
6768 |
+
// disable ARIA support, the live region takes care of that
|
6769 |
+
role: null
|
6770 |
+
})
|
6771 |
+
.hide()
|
6772 |
+
.data( "ui-menu" );
|
6773 |
|
6774 |
+
this._on( this.menu.element, {
|
6775 |
+
mousedown: function( event ) {
|
6776 |
+
// prevent moving focus out of the text field
|
6777 |
+
event.preventDefault();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6778 |
|
6779 |
+
// IE doesn't prevent moving focus even with event.preventDefault()
|
6780 |
+
// so we set a flag to know when we should ignore the blur event
|
6781 |
+
this.cancelBlur = true;
|
6782 |
+
this._delay(function() {
|
6783 |
+
delete this.cancelBlur;
|
6784 |
+
});
|
6785 |
|
6786 |
+
// clicking on the scrollbar causes focus to shift to the body
|
6787 |
+
// but we can't detect a mouseup or a click immediately afterward
|
6788 |
+
// so we have to track the next mousedown and close the menu if
|
6789 |
+
// the user clicks somewhere outside of the autocomplete
|
6790 |
+
var menuElement = this.menu.element[ 0 ];
|
6791 |
+
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
|
6792 |
+
this._delay(function() {
|
6793 |
+
var that = this;
|
6794 |
+
this.document.one( "mousedown", function( event ) {
|
6795 |
+
if ( event.target !== that.element[ 0 ] &&
|
6796 |
+
event.target !== menuElement &&
|
6797 |
+
!$.contains( menuElement, event.target ) ) {
|
6798 |
+
that.close();
|
6799 |
+
}
|
6800 |
+
});
|
6801 |
+
});
|
6802 |
+
}
|
6803 |
+
},
|
6804 |
+
menufocus: function( event, ui ) {
|
6805 |
+
// support: Firefox
|
6806 |
+
// Prevent accidental activation of menu items in Firefox (#7024 #9118)
|
6807 |
+
if ( this.isNewMenu ) {
|
6808 |
+
this.isNewMenu = false;
|
6809 |
+
if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
|
6810 |
+
this.menu.blur();
|
6811 |
+
|
6812 |
+
this.document.one( "mousemove", function() {
|
6813 |
+
$( event.target ).trigger( event.originalEvent );
|
6814 |
+
});
|
6815 |
+
|
6816 |
+
return;
|
6817 |
}
|
|
|
|
|
|
|
6818 |
}
|
|
|
|
|
|
|
|
|
6819 |
|
6820 |
+
var item = ui.item.data( "ui-autocomplete-item" );
|
6821 |
+
if ( false !== this._trigger( "focus", event, { item: item } ) ) {
|
6822 |
+
// use value to match what will end up in the input, if it was a key event
|
6823 |
+
if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
|
6824 |
+
this._value( item.value );
|
6825 |
+
}
|
6826 |
+
} else {
|
6827 |
+
// Normally the input is populated with the item's value as the
|
6828 |
+
// menu is navigated, causing screen readers to notice a change and
|
6829 |
+
// announce the item. Since the focus event was canceled, this doesn't
|
6830 |
+
// happen, so we update the live region so that screen readers can
|
6831 |
+
// still notice the change and announce it.
|
6832 |
+
this.liveRegion.text( item.value );
|
6833 |
+
}
|
6834 |
+
},
|
6835 |
+
menuselect: function( event, ui ) {
|
6836 |
+
var item = ui.item.data( "ui-autocomplete-item" ),
|
6837 |
+
previous = this.previous;
|
6838 |
+
|
6839 |
+
// only trigger when focus was lost (click on menu)
|
6840 |
+
if ( this.element[0] !== this.document[0].activeElement ) {
|
6841 |
+
this.element.focus();
|
6842 |
+
this.previous = previous;
|
6843 |
+
// #6109 - IE triggers two focus events and the second
|
6844 |
+
// is asynchronous, so we need to reset the previous
|
6845 |
+
// term synchronously and asynchronously :-(
|
6846 |
+
this._delay(function() {
|
6847 |
+
this.previous = previous;
|
6848 |
+
this.selectedItem = item;
|
6849 |
+
});
|
6850 |
+
}
|
6851 |
|
6852 |
+
if ( false !== this._trigger( "select", event, { item: item } ) ) {
|
6853 |
+
this._value( item.value );
|
6854 |
+
}
|
6855 |
+
// reset the term after the select event
|
6856 |
+
// this allows custom select handling to work properly
|
6857 |
+
this.term = this._value();
|
6858 |
|
6859 |
+
this.close( event );
|
6860 |
+
this.selectedItem = item;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6861 |
}
|
6862 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6863 |
|
6864 |
+
this.liveRegion = $( "<span>", {
|
6865 |
+
role: "status",
|
6866 |
+
"aria-live": "polite"
|
6867 |
+
})
|
6868 |
+
.addClass( "ui-helper-hidden-accessible" )
|
6869 |
+
.insertAfter( this.element );
|
|
|
|
|
6870 |
|
6871 |
+
// turning off autocomplete prevents the browser from remembering the
|
6872 |
+
// value when navigating through history, so we re-enable autocomplete
|
6873 |
+
// if the page is unloaded before the widget is destroyed. #7790
|
6874 |
+
this._on( this.window, {
|
6875 |
+
beforeunload: function() {
|
6876 |
+
this.element.removeAttr( "autocomplete" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6877 |
}
|
6878 |
+
});
|
|
|
|
|
6879 |
},
|
6880 |
|
6881 |
+
_destroy: function() {
|
6882 |
+
clearTimeout( this.searching );
|
6883 |
+
this.element
|
6884 |
+
.removeClass( "ui-autocomplete-input" )
|
6885 |
+
.removeAttr( "autocomplete" );
|
6886 |
+
this.menu.element.remove();
|
6887 |
+
this.liveRegion.remove();
|
|
|
6888 |
},
|
6889 |
|
6890 |
+
_setOption: function( key, value ) {
|
6891 |
+
this._super( key, value );
|
6892 |
+
if ( key === "source" ) {
|
6893 |
+
this._initSource();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6894 |
}
|
6895 |
+
if ( key === "appendTo" ) {
|
6896 |
+
this.menu.element.appendTo( this._appendTo() );
|
|
|
|
|
|
|
6897 |
}
|
6898 |
+
if ( key === "disabled" && value && this.xhr ) {
|
6899 |
+
this.xhr.abort();
|
|
|
|
|
|
|
|
|
6900 |
}
|
6901 |
},
|
6902 |
|
6903 |
+
_appendTo: function() {
|
6904 |
+
var element = this.options.appendTo;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6905 |
|
6906 |
+
if ( element ) {
|
6907 |
+
element = element.jquery || element.nodeType ?
|
6908 |
+
$( element ) :
|
6909 |
+
this.document.find( element ).eq( 0 );
|
6910 |
}
|
6911 |
+
|
6912 |
+
if ( !element ) {
|
6913 |
+
element = this.element.closest( ".ui-front" );
|
6914 |
}
|
|
|
6915 |
|
6916 |
+
if ( !element.length ) {
|
6917 |
+
element = this.document[0].body;
|
6918 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6919 |
|
6920 |
+
return element;
|
6921 |
+
},
|
|
|
|
|
6922 |
|
6923 |
+
_initSource: function() {
|
6924 |
+
var array, url,
|
6925 |
+
that = this;
|
6926 |
+
if ( $.isArray(this.options.source) ) {
|
6927 |
+
array = this.options.source;
|
6928 |
+
this.source = function( request, response ) {
|
6929 |
+
response( $.ui.autocomplete.filter( array, request.term ) );
|
6930 |
+
};
|
6931 |
+
} else if ( typeof this.options.source === "string" ) {
|
6932 |
+
url = this.options.source;
|
6933 |
+
this.source = function( request, response ) {
|
6934 |
+
if ( that.xhr ) {
|
6935 |
+
that.xhr.abort();
|
6936 |
}
|
6937 |
+
that.xhr = $.ajax({
|
6938 |
+
url: url,
|
6939 |
+
data: request,
|
6940 |
+
dataType: "json",
|
6941 |
+
success: function( data ) {
|
6942 |
+
response( data );
|
6943 |
+
},
|
6944 |
+
error: function() {
|
6945 |
+
response( [] );
|
6946 |
+
}
|
6947 |
+
});
|
6948 |
+
};
|
6949 |
+
} else {
|
6950 |
+
this.source = this.options.source;
|
6951 |
}
|
|
|
|
|
6952 |
},
|
6953 |
|
6954 |
+
_searchTimeout: function( event ) {
|
6955 |
+
clearTimeout( this.searching );
|
6956 |
+
this.searching = this._delay(function() {
|
6957 |
+
// only search if the value has changed
|
6958 |
+
if ( this.term !== this._value() ) {
|
6959 |
+
this.selectedItem = null;
|
6960 |
+
this.search( null, event );
|
6961 |
+
}
|
6962 |
+
}, this.options.delay );
|
6963 |
+
},
|
6964 |
|
6965 |
+
search: function( value, event ) {
|
6966 |
+
value = value != null ? value : this._value();
|
|
|
|
|
|
|
|
|
6967 |
|
6968 |
+
// always save the actual value, not the one passed as an argument
|
6969 |
+
this.term = this._value();
|
|
|
6970 |
|
6971 |
+
if ( value.length < this.options.minLength ) {
|
6972 |
+
return this.close( event );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6973 |
}
|
6974 |
|
6975 |
+
if ( this._trigger( "search", event ) === false ) {
|
6976 |
+
return;
|
6977 |
}
|
|
|
|
|
6978 |
|
6979 |
+
return this._search( value );
|
6980 |
+
},
|
6981 |
|
6982 |
+
_search: function( value ) {
|
6983 |
+
this.pending++;
|
6984 |
+
this.element.addClass( "ui-autocomplete-loading" );
|
6985 |
+
this.cancelSearch = false;
|
6986 |
|
6987 |
+
this.source( { term: value }, this._response() );
|
|
|
|
|
|
|
|
|
|
|
|
|
6988 |
},
|
6989 |
|
6990 |
+
_response: function() {
|
6991 |
+
var that = this,
|
6992 |
+
index = ++requestIndex;
|
|
|
6993 |
|
6994 |
+
return function( content ) {
|
6995 |
+
if ( index === requestIndex ) {
|
6996 |
+
that.__response( content );
|
6997 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6998 |
|
6999 |
+
that.pending--;
|
7000 |
+
if ( !that.pending ) {
|
7001 |
+
that.element.removeClass( "ui-autocomplete-loading" );
|
7002 |
+
}
|
7003 |
+
};
|
7004 |
+
},
|
|
|
|
|
|
|
7005 |
|
7006 |
+
__response: function( content ) {
|
7007 |
+
if ( content ) {
|
7008 |
+
content = this._normalize( content );
|
7009 |
}
|
7010 |
+
this._trigger( "response", null, { content: content } );
|
7011 |
+
if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
|
7012 |
+
this._suggest( content );
|
7013 |
+
this._trigger( "open" );
|
7014 |
+
} else {
|
7015 |
+
// use ._close() instead of .close() so we don't cancel future searches
|
7016 |
+
this._close();
|
|
|
|
|
|
|
7017 |
}
|
7018 |
+
},
|
7019 |
|
7020 |
+
close: function( event ) {
|
7021 |
+
this.cancelSearch = true;
|
7022 |
+
this._close( event );
|
7023 |
},
|
7024 |
|
7025 |
+
_close: function( event ) {
|
7026 |
+
if ( this.menu.element.is( ":visible" ) ) {
|
7027 |
+
this.menu.element.hide();
|
7028 |
+
this.menu.blur();
|
7029 |
+
this.isNewMenu = true;
|
7030 |
+
this._trigger( "close", event );
|
7031 |
}
|
7032 |
+
},
|
7033 |
|
7034 |
+
_change: function( event ) {
|
7035 |
+
if ( this.previous !== this._value() ) {
|
7036 |
+
this._trigger( "change", event, { item: this.selectedItem } );
|
7037 |
}
|
7038 |
+
},
|
7039 |
|
7040 |
+
_normalize: function( items ) {
|
7041 |
+
// assume all items have the right format when the first item is complete
|
7042 |
+
if ( items.length && items[0].label && items[0].value ) {
|
7043 |
+
return items;
|
7044 |
+
}
|
7045 |
+
return $.map( items, function( item ) {
|
7046 |
+
if ( typeof item === "string" ) {
|
7047 |
+
return {
|
7048 |
+
label: item,
|
7049 |
+
value: item
|
7050 |
+
};
|
7051 |
+
}
|
7052 |
+
return $.extend({
|
7053 |
+
label: item.label || item.value,
|
7054 |
+
value: item.value || item.label
|
7055 |
+
}, item );
|
7056 |
});
|
|
|
7057 |
},
|
7058 |
|
7059 |
+
_suggest: function( items ) {
|
7060 |
+
var ul = this.menu.element.empty();
|
7061 |
+
this._renderMenu( ul, items );
|
7062 |
+
this.isNewMenu = true;
|
7063 |
+
this.menu.refresh();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7064 |
|
7065 |
+
// size and position menu
|
7066 |
+
ul.show();
|
7067 |
+
this._resizeMenu();
|
7068 |
+
ul.position( $.extend({
|
7069 |
+
of: this.element
|
7070 |
+
}, this.options.position ));
|
7071 |
+
|
7072 |
+
if ( this.options.autoFocus ) {
|
7073 |
+
this.menu.next();
|
7074 |
}
|
7075 |
},
|
7076 |
|
7077 |
+
_resizeMenu: function() {
|
7078 |
+
var ul = this.menu.element;
|
7079 |
+
ul.outerWidth( Math.max(
|
7080 |
+
// Firefox wraps long text (possibly a rounding bug)
|
7081 |
+
// so we add 1px to avoid the wrapping (#7513)
|
7082 |
+
ul.width( "" ).outerWidth() + 1,
|
7083 |
+
this.element.outerWidth()
|
7084 |
+
) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7085 |
},
|
7086 |
|
7087 |
+
_renderMenu: function( ul, items ) {
|
7088 |
+
var that = this;
|
7089 |
+
$.each( items, function( index, item ) {
|
7090 |
+
that._renderItemData( ul, item );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7091 |
});
|
7092 |
+
},
|
7093 |
|
7094 |
+
_renderItemData: function( ul, item ) {
|
7095 |
+
return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
|
7096 |
+
},
|
7097 |
+
|
7098 |
+
_renderItem: function( ul, item ) {
|
7099 |
+
return $( "<li>" )
|
7100 |
+
.append( $( "<a>" ).text( item.label ) )
|
7101 |
+
.appendTo( ul );
|
7102 |
+
},
|
7103 |
+
|
7104 |
+
_move: function( direction, event ) {
|
7105 |
+
if ( !this.menu.element.is( ":visible" ) ) {
|
7106 |
+
this.search( null, event );
|
7107 |
+
return;
|
7108 |
+
}
|
7109 |
+
if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
|
7110 |
+
this.menu.isLastItem() && /^next/.test( direction ) ) {
|
7111 |
+
this._value( this.term );
|
7112 |
+
this.menu.blur();
|
7113 |
+
return;
|
7114 |
+
}
|
7115 |
+
this.menu[ direction ]( event );
|
7116 |
+
},
|
7117 |
+
|
7118 |
+
widget: function() {
|
7119 |
+
return this.menu.element;
|
7120 |
+
},
|
7121 |
+
|
7122 |
+
_value: function() {
|
7123 |
+
return this.valueMethod.apply( this.element, arguments );
|
7124 |
+
},
|
7125 |
+
|
7126 |
+
_keyEvent: function( keyEvent, event ) {
|
7127 |
+
if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
|
7128 |
+
this._move( keyEvent, event );
|
7129 |
+
|
7130 |
+
// prevents moving cursor to beginning/end of the text field in some browsers
|
7131 |
+
event.preventDefault();
|
7132 |
+
}
|
7133 |
}
|
7134 |
});
|
7135 |
|
7136 |
+
$.extend( $.ui.autocomplete, {
|
7137 |
+
escapeRegex: function( value ) {
|
7138 |
+
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
|
7139 |
+
},
|
7140 |
+
filter: function(array, term) {
|
7141 |
+
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
|
7142 |
+
return $.grep( array, function(value) {
|
7143 |
+
return matcher.test( value.label || value.value || value );
|
7144 |
+
});
|
7145 |
}
|
7146 |
});
|
7147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7148 |
|
7149 |
+
// live region extension, adding a `messages` option
|
7150 |
+
// NOTE: This is an experimental API. We are still investigating
|
7151 |
+
// a full solution for string manipulation and internationalization.
|
7152 |
+
$.widget( "ui.autocomplete", $.ui.autocomplete, {
|
7153 |
options: {
|
7154 |
+
messages: {
|
7155 |
+
noResults: "No search results.",
|
7156 |
+
results: function( amount ) {
|
7157 |
+
return amount + ( amount > 1 ? " results are" : " result is" ) +
|
7158 |
+
" available, use up and down arrow keys to navigate.";
|
7159 |
+
}
|
7160 |
+
}
|
|
|
|
|
7161 |
},
|
7162 |
|
7163 |
+
__response: function( content ) {
|
7164 |
+
var message;
|
7165 |
+
this._superApply( arguments );
|
7166 |
+
if ( this.options.disabled || this.cancelSearch ) {
|
7167 |
+
return;
|
7168 |
+
}
|
7169 |
+
if ( content && content.length ) {
|
7170 |
+
message = this.options.messages.results( content.length );
|
7171 |
+
} else {
|
7172 |
+
message = this.options.messages.noResults;
|
7173 |
+
}
|
7174 |
+
this.liveRegion.text( message );
|
7175 |
+
}
|
7176 |
+
});
|
7177 |
|
7178 |
+
}( jQuery ));
|
|
|
|
|
|
|
|
|
|
|
|
|
7179 |
|
7180 |
+
(function( $, undefined ) {
|
7181 |
|
7182 |
+
var lastActive, startXPos, startYPos, clickDragged,
|
7183 |
+
baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
|
7184 |
+
stateClasses = "ui-state-hover ui-state-active ",
|
7185 |
+
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",
|
7186 |
+
formResetHandler = function() {
|
7187 |
+
var buttons = $( this ).find( ":ui-button" );
|
7188 |
+
setTimeout(function() {
|
7189 |
+
buttons.button( "refresh" );
|
7190 |
+
}, 1 );
|
7191 |
+
},
|
7192 |
+
radioGroup = function( radio ) {
|
7193 |
+
var name = radio.name,
|
7194 |
+
form = radio.form,
|
7195 |
+
radios = $( [] );
|
7196 |
+
if ( name ) {
|
7197 |
+
name = name.replace( /'/g, "\\'" );
|
7198 |
+
if ( form ) {
|
7199 |
+
radios = $( form ).find( "[name='" + name + "']" );
|
7200 |
+
} else {
|
7201 |
+
radios = $( "[name='" + name + "']", radio.ownerDocument )
|
7202 |
+
.filter(function() {
|
7203 |
+
return !this.form;
|
7204 |
+
});
|
7205 |
}
|
7206 |
+
}
|
7207 |
+
return radios;
|
7208 |
+
};
|
7209 |
|
7210 |
+
$.widget( "ui.button", {
|
7211 |
+
version: "1.10.2",
|
7212 |
+
defaultElement: "<button>",
|
7213 |
+
options: {
|
7214 |
+
disabled: null,
|
7215 |
+
text: true,
|
7216 |
+
label: null,
|
7217 |
+
icons: {
|
7218 |
+
primary: null,
|
7219 |
+
secondary: null
|
7220 |
}
|
7221 |
+
},
|
7222 |
+
_create: function() {
|
7223 |
+
this.element.closest( "form" )
|
7224 |
+
.unbind( "reset" + this.eventNamespace )
|
7225 |
+
.bind( "reset" + this.eventNamespace, formResetHandler );
|
7226 |
|
7227 |
+
if ( typeof this.options.disabled !== "boolean" ) {
|
7228 |
+
this.options.disabled = !!this.element.prop( "disabled" );
|
7229 |
+
} else {
|
7230 |
+
this.element.prop( "disabled", this.options.disabled );
|
7231 |
}
|
7232 |
|
7233 |
+
this._determineButtonType();
|
7234 |
+
this.hasTitle = !!this.buttonElement.attr( "title" );
|
7235 |
|
7236 |
+
var that = this,
|
7237 |
+
options = this.options,
|
7238 |
+
toggleButton = this.type === "checkbox" || this.type === "radio",
|
7239 |
+
activeClass = !toggleButton ? "ui-state-active" : "",
|
7240 |
+
focusClass = "ui-state-focus";
|
7241 |
|
7242 |
+
if ( options.label === null ) {
|
7243 |
+
options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
|
7244 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7245 |
|
7246 |
+
this._hoverable( this.buttonElement );
|
|
|
|
|
7247 |
|
7248 |
+
this.buttonElement
|
7249 |
+
.addClass( baseClasses )
|
7250 |
+
.attr( "role", "button" )
|
7251 |
+
.bind( "mouseenter" + this.eventNamespace, function() {
|
7252 |
+
if ( options.disabled ) {
|
|
|
|
|
|
|
|
|
|
|
7253 |
return;
|
7254 |
}
|
7255 |
+
if ( this === lastActive ) {
|
7256 |
+
$( this ).addClass( "ui-state-active" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7257 |
}
|
7258 |
+
})
|
7259 |
+
.bind( "mouseleave" + this.eventNamespace, function() {
|
7260 |
+
if ( options.disabled ) {
|
7261 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7262 |
}
|
7263 |
+
$( this ).removeClass( activeClass );
|
|
|
|
|
|
|
|
|
7264 |
})
|
7265 |
+
.bind( "click" + this.eventNamespace, function( event ) {
|
7266 |
+
if ( options.disabled ) {
|
7267 |
+
event.preventDefault();
|
7268 |
+
event.stopImmediatePropagation();
|
|
|
|
|
|
|
|
|
7269 |
}
|
|
|
7270 |
});
|
7271 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7272 |
this.element
|
7273 |
+
.bind( "focus" + this.eventNamespace, function() {
|
7274 |
+
// no need to check disabled, focus won't be triggered anyway
|
7275 |
+
that.buttonElement.addClass( focusClass );
|
7276 |
+
})
|
7277 |
+
.bind( "blur" + this.eventNamespace, function() {
|
7278 |
+
that.buttonElement.removeClass( focusClass );
|
7279 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7280 |
|
7281 |
+
if ( toggleButton ) {
|
7282 |
+
this.element.bind( "change" + this.eventNamespace, function() {
|
7283 |
+
if ( clickDragged ) {
|
7284 |
+
return;
|
7285 |
+
}
|
7286 |
+
that.refresh();
|
7287 |
+
});
|
7288 |
+
// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
|
7289 |
+
// prevents issue where button state changes but checkbox/radio checked state
|
7290 |
+
// does not in Firefox (see ticket #6970)
|
7291 |
+
this.buttonElement
|
7292 |
+
.bind( "mousedown" + this.eventNamespace, function( event ) {
|
7293 |
+
if ( options.disabled ) {
|
7294 |
+
return;
|
7295 |
+
}
|
7296 |
+
clickDragged = false;
|
7297 |
+
startXPos = event.pageX;
|
7298 |
+
startYPos = event.pageY;
|
7299 |
+
})
|
7300 |
+
.bind( "mouseup" + this.eventNamespace, function( event ) {
|
7301 |
+
if ( options.disabled ) {
|
7302 |
+
return;
|
7303 |
+
}
|
7304 |
+
if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
|
7305 |
+
clickDragged = true;
|
7306 |
+
}
|
7307 |
+
});
|
7308 |
}
|
7309 |
|
7310 |
+
if ( this.type === "checkbox" ) {
|
7311 |
+
this.buttonElement.bind( "click" + this.eventNamespace, function() {
|
7312 |
+
if ( options.disabled || clickDragged ) {
|
7313 |
+
return false;
|
7314 |
+
}
|
7315 |
+
});
|
7316 |
+
} else if ( this.type === "radio" ) {
|
7317 |
+
this.buttonElement.bind( "click" + this.eventNamespace, function() {
|
7318 |
+
if ( options.disabled || clickDragged ) {
|
7319 |
+
return false;
|
7320 |
+
}
|
7321 |
+
$( this ).addClass( "ui-state-active" );
|
7322 |
+
that.buttonElement.attr( "aria-pressed", "true" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7323 |
|
7324 |
+
var radio = that.element[ 0 ];
|
7325 |
+
radioGroup( radio )
|
7326 |
+
.not( radio )
|
7327 |
+
.map(function() {
|
7328 |
+
return $( this ).button( "widget" )[ 0 ];
|
7329 |
+
})
|
7330 |
+
.removeClass( "ui-state-active" )
|
7331 |
+
.attr( "aria-pressed", "false" );
|
7332 |
+
});
|
7333 |
+
} else {
|
7334 |
+
this.buttonElement
|
7335 |
+
.bind( "mousedown" + this.eventNamespace, function() {
|
7336 |
+
if ( options.disabled ) {
|
7337 |
+
return false;
|
7338 |
+
}
|
7339 |
+
$( this ).addClass( "ui-state-active" );
|
7340 |
+
lastActive = this;
|
7341 |
+
that.document.one( "mouseup", function() {
|
7342 |
+
lastActive = null;
|
7343 |
+
});
|
7344 |
+
})
|
7345 |
+
.bind( "mouseup" + this.eventNamespace, function() {
|
7346 |
+
if ( options.disabled ) {
|
7347 |
+
return false;
|
7348 |
+
}
|
7349 |
+
$( this ).removeClass( "ui-state-active" );
|
7350 |
+
})
|
7351 |
+
.bind( "keydown" + this.eventNamespace, function(event) {
|
7352 |
+
if ( options.disabled ) {
|
7353 |
+
return false;
|
7354 |
+
}
|
7355 |
+
if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
|
7356 |
+
$( this ).addClass( "ui-state-active" );
|
7357 |
+
}
|
7358 |
+
})
|
7359 |
+
// see #8559, we bind to blur here in case the button element loses
|
7360 |
+
// focus between keydown and keyup, it would be left in an "active" state
|
7361 |
+
.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
|
7362 |
+
$( this ).removeClass( "ui-state-active" );
|
7363 |
+
});
|
7364 |
|
7365 |
+
if ( this.buttonElement.is("a") ) {
|
7366 |
+
this.buttonElement.keyup(function(event) {
|
7367 |
+
if ( event.keyCode === $.ui.keyCode.SPACE ) {
|
7368 |
+
// TODO pass through original event correctly (just as 2nd argument doesn't work)
|
7369 |
+
$( this ).click();
|
7370 |
+
}
|
7371 |
+
});
|
7372 |
+
}
|
7373 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7374 |
|
7375 |
+
// TODO: pull out $.Widget's handling for the disabled option into
|
7376 |
+
// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
|
7377 |
+
// be overridden by individual plugins
|
7378 |
+
this._setOption( "disabled", options.disabled );
|
7379 |
+
this._resetButton();
|
7380 |
},
|
7381 |
|
7382 |
+
_determineButtonType: function() {
|
7383 |
+
var ancestor, labelSelector, checked;
|
|
|
7384 |
|
7385 |
+
if ( this.element.is("[type=checkbox]") ) {
|
7386 |
+
this.type = "checkbox";
|
7387 |
+
} else if ( this.element.is("[type=radio]") ) {
|
7388 |
+
this.type = "radio";
|
7389 |
+
} else if ( this.element.is("input") ) {
|
7390 |
+
this.type = "input";
|
7391 |
+
} else {
|
7392 |
+
this.type = "button";
|
7393 |
+
}
|
7394 |
|
7395 |
+
if ( this.type === "checkbox" || this.type === "radio" ) {
|
7396 |
+
// we don't search against the document in case the element
|
7397 |
+
// is disconnected from the DOM
|
7398 |
+
ancestor = this.element.parents().last();
|
7399 |
+
labelSelector = "label[for='" + this.element.attr("id") + "']";
|
7400 |
+
this.buttonElement = ancestor.find( labelSelector );
|
7401 |
+
if ( !this.buttonElement.length ) {
|
7402 |
+
ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
|
7403 |
+
this.buttonElement = ancestor.filter( labelSelector );
|
7404 |
+
if ( !this.buttonElement.length ) {
|
7405 |
+
this.buttonElement = ancestor.find( labelSelector );
|
7406 |
+
}
|
7407 |
+
}
|
7408 |
+
this.element.addClass( "ui-helper-hidden-accessible" );
|
7409 |
|
7410 |
+
checked = this.element.is( ":checked" );
|
7411 |
+
if ( checked ) {
|
7412 |
+
this.buttonElement.addClass( "ui-state-active" );
|
7413 |
+
}
|
7414 |
+
this.buttonElement.prop( "aria-pressed", checked );
|
7415 |
+
} else {
|
7416 |
+
this.buttonElement = this.element;
|
7417 |
+
}
|
7418 |
},
|
7419 |
+
|
7420 |
+
widget: function() {
|
7421 |
+
return this.buttonElement;
|
7422 |
},
|
7423 |
|
7424 |
+
_destroy: function() {
|
7425 |
+
this.element
|
7426 |
+
.removeClass( "ui-helper-hidden-accessible" );
|
7427 |
+
this.buttonElement
|
7428 |
+
.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
|
7429 |
+
.removeAttr( "role" )
|
7430 |
+
.removeAttr( "aria-pressed" )
|
7431 |
+
.html( this.buttonElement.find(".ui-button-text").html() );
|
7432 |
|
7433 |
+
if ( !this.hasTitle ) {
|
7434 |
+
this.buttonElement.removeAttr( "title" );
|
|
|
|
|
|
|
|
|
7435 |
}
|
7436 |
+
},
|
7437 |
|
7438 |
+
_setOption: function( key, value ) {
|
7439 |
+
this._super( key, value );
|
7440 |
+
if ( key === "disabled" ) {
|
7441 |
+
if ( value ) {
|
7442 |
+
this.element.prop( "disabled", true );
|
7443 |
+
} else {
|
7444 |
+
this.element.prop( "disabled", false );
|
7445 |
+
}
|
7446 |
+
return;
|
7447 |
}
|
7448 |
+
this._resetButton();
|
7449 |
+
},
|
7450 |
|
7451 |
+
refresh: function() {
|
7452 |
+
//See #8237 & #8828
|
7453 |
+
var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
|
7454 |
|
7455 |
+
if ( isDisabled !== this.options.disabled ) {
|
7456 |
+
this._setOption( "disabled", isDisabled );
|
7457 |
+
}
|
7458 |
+
if ( this.type === "radio" ) {
|
7459 |
+
radioGroup( this.element[0] ).each(function() {
|
7460 |
+
if ( $( this ).is( ":checked" ) ) {
|
7461 |
+
$( this ).button( "widget" )
|
7462 |
+
.addClass( "ui-state-active" )
|
7463 |
+
.attr( "aria-pressed", "true" );
|
7464 |
+
} else {
|
7465 |
+
$( this ).button( "widget" )
|
7466 |
+
.removeClass( "ui-state-active" )
|
7467 |
+
.attr( "aria-pressed", "false" );
|
7468 |
+
}
|
7469 |
+
});
|
7470 |
+
} else if ( this.type === "checkbox" ) {
|
7471 |
+
if ( this.element.is( ":checked" ) ) {
|
7472 |
+
this.buttonElement
|
7473 |
+
.addClass( "ui-state-active" )
|
7474 |
+
.attr( "aria-pressed", "true" );
|
7475 |
+
} else {
|
7476 |
+
this.buttonElement
|
7477 |
+
.removeClass( "ui-state-active" )
|
7478 |
+
.attr( "aria-pressed", "false" );
|
7479 |
+
}
|
7480 |
+
}
|
7481 |
},
|
7482 |
|
7483 |
+
_resetButton: function() {
|
7484 |
+
if ( this.type === "input" ) {
|
7485 |
+
if ( this.options.label ) {
|
7486 |
+
this.element.val( this.options.label );
|
7487 |
+
}
|
7488 |
+
return;
|
|
|
|
|
7489 |
}
|
7490 |
+
var buttonElement = this.buttonElement.removeClass( typeClasses ),
|
7491 |
+
buttonText = $( "<span></span>", this.document[0] )
|
7492 |
+
.addClass( "ui-button-text" )
|
7493 |
+
.html( this.options.label )
|
7494 |
+
.appendTo( buttonElement.empty() )
|
7495 |
+
.text(),
|
7496 |
+
icons = this.options.icons,
|
7497 |
+
multipleIcons = icons.primary && icons.secondary,
|
7498 |
+
buttonClasses = [];
|
7499 |
|
7500 |
+
if ( icons.primary || icons.secondary ) {
|
7501 |
+
if ( this.options.text ) {
|
7502 |
+
buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
|
7503 |
+
}
|
7504 |
|
7505 |
+
if ( icons.primary ) {
|
7506 |
+
buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
|
7507 |
+
}
|
7508 |
|
7509 |
+
if ( icons.secondary ) {
|
7510 |
+
buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
|
|
|
|
|
7511 |
}
|
7512 |
|
7513 |
+
if ( !this.options.text ) {
|
7514 |
+
buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
|
7515 |
+
|
7516 |
+
if ( !this.hasTitle ) {
|
7517 |
+
buttonElement.attr( "title", $.trim( buttonText ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7518 |
}
|
7519 |
}
|
7520 |
} else {
|
7521 |
+
buttonClasses.push( "ui-button-text-only" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7522 |
}
|
7523 |
+
buttonElement.addClass( buttonClasses.join( " " ) );
|
7524 |
+
}
|
7525 |
+
});
|
7526 |
|
7527 |
+
$.widget( "ui.buttonset", {
|
7528 |
+
version: "1.10.2",
|
7529 |
+
options: {
|
7530 |
+
items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
|
7531 |
},
|
7532 |
|
7533 |
+
_create: function() {
|
7534 |
+
this.element.addClass( "ui-buttonset" );
|
7535 |
+
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7536 |
|
7537 |
+
_init: function() {
|
7538 |
+
this.refresh();
|
7539 |
},
|
7540 |
|
7541 |
+
_setOption: function( key, value ) {
|
7542 |
+
if ( key === "disabled" ) {
|
7543 |
+
this.buttons.button( "option", key, value );
|
|
|
|
|
|
|
7544 |
}
|
7545 |
|
7546 |
+
this._super( key, value );
|
7547 |
},
|
7548 |
|
7549 |
+
refresh: function() {
|
7550 |
+
var rtl = this.element.css( "direction" ) === "rtl";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7551 |
|
7552 |
+
this.buttons = this.element.find( this.options.items )
|
7553 |
+
.filter( ":ui-button" )
|
7554 |
+
.button( "refresh" )
|
7555 |
+
.end()
|
7556 |
+
.not( ":ui-button" )
|
7557 |
+
.button()
|
7558 |
+
.end()
|
7559 |
+
.map(function() {
|
7560 |
+
return $( this ).button( "widget" )[ 0 ];
|
7561 |
+
})
|
7562 |
+
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
|
7563 |
+
.filter( ":first" )
|
7564 |
+
.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
|
7565 |
+
.end()
|
7566 |
+
.filter( ":last" )
|
7567 |
+
.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
|
7568 |
+
.end()
|
7569 |
+
.end();
|
|
|
7570 |
},
|
7571 |
|
7572 |
+
_destroy: function() {
|
7573 |
+
this.element.removeClass( "ui-buttonset" );
|
7574 |
+
this.buttons
|
7575 |
+
.map(function() {
|
7576 |
+
return $( this ).button( "widget" )[ 0 ];
|
7577 |
+
})
|
7578 |
+
.removeClass( "ui-corner-left ui-corner-right" )
|
7579 |
+
.end()
|
7580 |
+
.button( "destroy" );
|
7581 |
+
}
|
7582 |
+
});
|
7583 |
|
7584 |
+
}( jQuery ) );
|
|
|
|
|
7585 |
|
7586 |
+
(function( $, undefined ) {
|
7587 |
|
7588 |
+
$.extend($.ui, { datepicker: { version: "1.10.2" } });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7589 |
|
7590 |
+
var PROP_NAME = "datepicker",
|
7591 |
+
dpuuid = new Date().getTime(),
|
7592 |
+
instActive;
|
|
|
|
|
7593 |
|
7594 |
+
/* Date picker manager.
|
7595 |
+
Use the singleton instance of this class, $.datepicker, to interact with the date picker.
|
7596 |
+
Settings for (groups of) date pickers are maintained in an instance object,
|
7597 |
+
allowing multiple different settings on the same page. */
|
7598 |
|
7599 |
+
function Datepicker() {
|
7600 |
+
this._curInst = null; // The current instance in use
|
7601 |
+
this._keyEvent = false; // If the last event was a key event
|
7602 |
+
this._disabledInputs = []; // List of date picker inputs that have been disabled
|
7603 |
+
this._datepickerShowing = false; // True if the popup picker is showing , false if not
|
7604 |
+
this._inDialog = false; // True if showing within a "dialog", false if not
|
7605 |
+
this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
|
7606 |
+
this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
|
7607 |
+
this._appendClass = "ui-datepicker-append"; // The name of the append marker class
|
7608 |
+
this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
|
7609 |
+
this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
|
7610 |
+
this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
|
7611 |
+
this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
|
7612 |
+
this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
|
7613 |
+
this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
|
7614 |
+
this.regional = []; // Available regional settings, indexed by language code
|
7615 |
+
this.regional[""] = { // Default regional settings
|
7616 |
+
closeText: "Done", // Display text for close link
|
7617 |
+
prevText: "Prev", // Display text for previous month link
|
7618 |
+
nextText: "Next", // Display text for next month link
|
7619 |
+
currentText: "Today", // Display text for current month link
|
7620 |
+
monthNames: ["January","February","March","April","May","June",
|
7621 |
+
"July","August","September","October","November","December"], // Names of months for drop-down and formatting
|
7622 |
+
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
|
7623 |
+
dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
|
7624 |
+
dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
|
7625 |
+
dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
|
7626 |
+
weekHeader: "Wk", // Column header for week of the year
|
7627 |
+
dateFormat: "mm/dd/yy", // See format options on parseDate
|
7628 |
+
firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
|
7629 |
+
isRTL: false, // True if right-to-left language, false if left-to-right
|
7630 |
+
showMonthAfterYear: false, // True if the year select precedes month, false for month then year
|
7631 |
+
yearSuffix: "" // Additional text to append to the year in the month headers
|
7632 |
+
};
|
7633 |
+
this._defaults = { // Global defaults for all the date picker instances
|
7634 |
+
showOn: "focus", // "focus" for popup on focus,
|
7635 |
+
// "button" for trigger button, or "both" for either
|
7636 |
+
showAnim: "fadeIn", // Name of jQuery animation for popup
|
7637 |
+
showOptions: {}, // Options for enhanced animations
|
7638 |
+
defaultDate: null, // Used when field is blank: actual date,
|
7639 |
+
// +/-number for offset from today, null for today
|
7640 |
+
appendText: "", // Display text following the input box, e.g. showing the format
|
7641 |
+
buttonText: "...", // Text for trigger button
|
7642 |
+
buttonImage: "", // URL for trigger button image
|
7643 |
+
buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
|
7644 |
+
hideIfNoPrevNext: false, // True to hide next/previous month links
|
7645 |
+
// if not applicable, false to just disable them
|
7646 |
+
navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
|
7647 |
+
gotoCurrent: false, // True if today link goes back to current selection instead
|
7648 |
+
changeMonth: false, // True if month can be selected directly, false if only prev/next
|
7649 |
+
changeYear: false, // True if year can be selected directly, false if only prev/next
|
7650 |
+
yearRange: "c-10:c+10", // Range of years to display in drop-down,
|
7651 |
+
// either relative to today's year (-nn:+nn), relative to currently displayed year
|
7652 |
+
// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
|
7653 |
+
showOtherMonths: false, // True to show dates in other months, false to leave blank
|
7654 |
+
selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
|
7655 |
+
showWeek: false, // True to show week of the year, false to not show it
|
7656 |
+
calculateWeek: this.iso8601Week, // How to calculate the week of the year,
|
7657 |
+
// takes a Date and returns the number of the week for it
|
7658 |
+
shortYearCutoff: "+10", // Short year values < this are in the current century,
|
7659 |
+
// > this are in the previous century,
|
7660 |
+
// string value starting with "+" for current year + value
|
7661 |
+
minDate: null, // The earliest selectable date, or null for no limit
|
7662 |
+
maxDate: null, // The latest selectable date, or null for no limit
|
7663 |
+
duration: "fast", // Duration of display/closure
|
7664 |
+
beforeShowDay: null, // Function that takes a date and returns an array with
|
7665 |
+
// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
|
7666 |
+
// [2] = cell title (optional), e.g. $.datepicker.noWeekends
|
7667 |
+
beforeShow: null, // Function that takes an input field and
|
7668 |
+
// returns a set of custom settings for the date picker
|
7669 |
+
onSelect: null, // Define a callback function when a date is selected
|
7670 |
+
onChangeMonthYear: null, // Define a callback function when the month or year is changed
|
7671 |
+
onClose: null, // Define a callback function when the datepicker is closed
|
7672 |
+
numberOfMonths: 1, // Number of months to show at a time
|
7673 |
+
showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
|
7674 |
+
stepMonths: 1, // Number of months to step back/forward
|
7675 |
+
stepBigMonths: 12, // Number of months to step back/forward for the big links
|
7676 |
+
altField: "", // Selector for an alternate field to store selected dates into
|
7677 |
+
altFormat: "", // The date format to use for the alternate field
|
7678 |
+
constrainInput: true, // The input is constrained by the current date format
|
7679 |
+
showButtonPanel: false, // True to show button panel, false to not show it
|
7680 |
+
autoSize: false, // True to size the input for the date format, false to leave as is
|
7681 |
+
disabled: false // The initial disabled state
|
7682 |
+
};
|
7683 |
+
$.extend(this._defaults, this.regional[""]);
|
7684 |
+
this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
|
7685 |
+
}
|
7686 |
|
7687 |
+
$.extend(Datepicker.prototype, {
|
7688 |
+
/* Class name added to elements to indicate already configured with a date picker. */
|
7689 |
+
markerClassName: "hasDatepicker",
|
7690 |
|
7691 |
+
//Keep track of the maximum number of rows displayed (see #7043)
|
7692 |
+
maxRows: 4,
|
|
|
|
|
|
|
|
|
|
|
|
|
7693 |
|
7694 |
+
// TODO rename to "widget" when switching to widget factory
|
7695 |
+
_widgetDatepicker: function() {
|
7696 |
+
return this.dpDiv;
|
7697 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7698 |
|
7699 |
+
/* Override the default settings for all instances of the date picker.
|
7700 |
+
* @param settings object - the new settings to use as defaults (anonymous object)
|
7701 |
+
* @return the manager object
|
7702 |
+
*/
|
7703 |
+
setDefaults: function(settings) {
|
7704 |
+
extendRemove(this._defaults, settings || {});
|
7705 |
+
return this;
|
7706 |
+
},
|
7707 |
|
7708 |
+
/* Attach the date picker to a jQuery selection.
|
7709 |
+
* @param target element - the target input field or division or span
|
7710 |
+
* @param settings object - the new settings to use for this date picker instance (anonymous)
|
7711 |
+
*/
|
7712 |
+
_attachDatepicker: function(target, settings) {
|
7713 |
+
var nodeName, inline, inst;
|
7714 |
+
nodeName = target.nodeName.toLowerCase();
|
7715 |
+
inline = (nodeName === "div" || nodeName === "span");
|
7716 |
+
if (!target.id) {
|
7717 |
+
this.uuid += 1;
|
7718 |
+
target.id = "dp" + this.uuid;
|
7719 |
+
}
|
7720 |
+
inst = this._newInst($(target), inline);
|
7721 |
+
inst.settings = $.extend({}, settings || {});
|
7722 |
+
if (nodeName === "input") {
|
7723 |
+
this._connectDatepicker(target, inst);
|
7724 |
+
} else if (inline) {
|
7725 |
+
this._inlineDatepicker(target, inst);
|
7726 |
+
}
|
7727 |
},
|
7728 |
|
7729 |
+
/* Create a new instance object. */
|
7730 |
+
_newInst: function(target, inline) {
|
7731 |
+
var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
|
7732 |
+
return {id: id, input: target, // associated target
|
7733 |
+
selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
|
7734 |
+
drawMonth: 0, drawYear: 0, // month being drawn
|
7735 |
+
inline: inline, // is datepicker inline or not
|
7736 |
+
dpDiv: (!inline ? this.dpDiv : // presentation div
|
7737 |
+
bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
|
7738 |
},
|
7739 |
|
7740 |
+
/* Attach the date picker to an input field. */
|
7741 |
+
_connectDatepicker: function(target, inst) {
|
7742 |
+
var input = $(target);
|
7743 |
+
inst.append = $([]);
|
7744 |
+
inst.trigger = $([]);
|
7745 |
+
if (input.hasClass(this.markerClassName)) {
|
7746 |
+
return;
|
7747 |
+
}
|
7748 |
+
this._attachments(input, inst);
|
7749 |
+
input.addClass(this.markerClassName).keydown(this._doKeyDown).
|
7750 |
+
keypress(this._doKeyPress).keyup(this._doKeyUp);
|
7751 |
+
this._autoSize(inst);
|
7752 |
+
$.data(target, PROP_NAME, inst);
|
7753 |
+
//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
|
7754 |
+
if( inst.settings.disabled ) {
|
7755 |
+
this._disableDatepicker( target );
|
7756 |
+
}
|
7757 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7758 |
|
7759 |
+
/* Make attachments based on settings. */
|
7760 |
+
_attachments: function(input, inst) {
|
7761 |
+
var showOn, buttonText, buttonImage,
|
7762 |
+
appendText = this._get(inst, "appendText"),
|
7763 |
+
isRTL = this._get(inst, "isRTL");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7764 |
|
7765 |
+
if (inst.append) {
|
7766 |
+
inst.append.remove();
|
7767 |
+
}
|
7768 |
+
if (appendText) {
|
7769 |
+
inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
|
7770 |
+
input[isRTL ? "before" : "after"](inst.append);
|
|
|
|
|
|
|
|
|
|
|
|
|
7771 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7772 |
|
7773 |
+
input.unbind("focus", this._showDatepicker);
|
|
|
|
|
7774 |
|
7775 |
+
if (inst.trigger) {
|
7776 |
+
inst.trigger.remove();
|
7777 |
+
}
|
7778 |
|
7779 |
+
showOn = this._get(inst, "showOn");
|
7780 |
+
if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
|
7781 |
+
input.focus(this._showDatepicker);
|
7782 |
+
}
|
7783 |
+
if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
|
7784 |
+
buttonText = this._get(inst, "buttonText");
|
7785 |
+
buttonImage = this._get(inst, "buttonImage");
|
7786 |
+
inst.trigger = $(this._get(inst, "buttonImageOnly") ?
|
7787 |
+
$("<img/>").addClass(this._triggerClass).
|
7788 |
+
attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
|
7789 |
+
$("<button type='button'></button>").addClass(this._triggerClass).
|
7790 |
+
html(!buttonImage ? buttonText : $("<img/>").attr(
|
7791 |
+
{ src:buttonImage, alt:buttonText, title:buttonText })));
|
7792 |
+
input[isRTL ? "before" : "after"](inst.trigger);
|
7793 |
+
inst.trigger.click(function() {
|
7794 |
+
if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
|
7795 |
+
$.datepicker._hideDatepicker();
|
7796 |
+
} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
|
7797 |
+
$.datepicker._hideDatepicker();
|
7798 |
+
$.datepicker._showDatepicker(input[0]);
|
7799 |
+
} else {
|
7800 |
+
$.datepicker._showDatepicker(input[0]);
|
7801 |
+
}
|
7802 |
+
return false;
|
7803 |
+
});
|
7804 |
+
}
|
7805 |
},
|
7806 |
|
7807 |
+
/* Apply the maximum length for the date format. */
|
7808 |
+
_autoSize: function(inst) {
|
7809 |
+
if (this._get(inst, "autoSize") && !inst.inline) {
|
7810 |
+
var findMax, max, maxI, i,
|
7811 |
+
date = new Date(2009, 12 - 1, 20), // Ensure double digits
|
7812 |
+
dateFormat = this._get(inst, "dateFormat");
|
7813 |
|
7814 |
+
if (dateFormat.match(/[DM]/)) {
|
7815 |
+
findMax = function(names) {
|
7816 |
+
max = 0;
|
7817 |
+
maxI = 0;
|
7818 |
+
for (i = 0; i < names.length; i++) {
|
7819 |
+
if (names[i].length > max) {
|
7820 |
+
max = names[i].length;
|
7821 |
+
maxI = i;
|
7822 |
+
}
|
7823 |
+
}
|
7824 |
+
return maxI;
|
7825 |
+
};
|
7826 |
+
date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
|
7827 |
+
"monthNames" : "monthNamesShort"))));
|
7828 |
+
date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
|
7829 |
+
"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
|
7830 |
}
|
7831 |
+
inst.input.attr("size", this._formatDate(inst, date).length);
|
|
|
|
|
|
|
7832 |
}
|
7833 |
},
|
7834 |
|
7835 |
+
/* Attach an inline date picker to a div. */
|
7836 |
+
_inlineDatepicker: function(target, inst) {
|
7837 |
+
var divSpan = $(target);
|
7838 |
+
if (divSpan.hasClass(this.markerClassName)) {
|
7839 |
+
return;
|
7840 |
+
}
|
7841 |
+
divSpan.addClass(this.markerClassName).append(inst.dpDiv);
|
7842 |
+
$.data(target, PROP_NAME, inst);
|
7843 |
+
this._setDate(inst, this._getDefaultDate(inst), true);
|
7844 |
+
this._updateDatepicker(inst);
|
7845 |
+
this._updateAlternate(inst);
|
7846 |
+
//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
|
7847 |
+
if( inst.settings.disabled ) {
|
7848 |
+
this._disableDatepicker( target );
|
7849 |
+
}
|
7850 |
+
// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
|
7851 |
+
// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
|
7852 |
+
inst.dpDiv.css( "display", "block" );
|
7853 |
},
|
7854 |
|
7855 |
+
/* Pop-up the date picker in a "dialog" box.
|
7856 |
+
* @param input element - ignored
|
7857 |
+
* @param date string or Date - the initial date to display
|
7858 |
+
* @param onSelect function - the function to call when a date is selected
|
7859 |
+
* @param settings object - update the dialog date picker instance's settings (anonymous object)
|
7860 |
+
* @param pos int[2] - coordinates for the dialog's position within the screen or
|
7861 |
+
* event - with x/y coordinates or
|
7862 |
+
* leave empty for default (screen centre)
|
7863 |
+
* @return the manager object
|
7864 |
+
*/
|
7865 |
+
_dialogDatepicker: function(input, date, onSelect, settings, pos) {
|
7866 |
+
var id, browserWidth, browserHeight, scrollX, scrollY,
|
7867 |
+
inst = this._dialogInst; // internal instance
|
7868 |
|
7869 |
+
if (!inst) {
|
7870 |
+
this.uuid += 1;
|
7871 |
+
id = "dp" + this.uuid;
|
7872 |
+
this._dialogInput = $("<input type='text' id='" + id +
|
7873 |
+
"' style='position: absolute; top: -100px; width: 0px;'/>");
|
7874 |
+
this._dialogInput.keydown(this._doKeyDown);
|
7875 |
+
$("body").append(this._dialogInput);
|
7876 |
+
inst = this._dialogInst = this._newInst(this._dialogInput, false);
|
7877 |
+
inst.settings = {};
|
7878 |
+
$.data(this._dialogInput[0], PROP_NAME, inst);
|
7879 |
+
}
|
7880 |
+
extendRemove(inst.settings, settings || {});
|
7881 |
+
date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
|
7882 |
+
this._dialogInput.val(date);
|
7883 |
|
7884 |
+
this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
|
7885 |
+
if (!this._pos) {
|
7886 |
+
browserWidth = document.documentElement.clientWidth;
|
7887 |
+
browserHeight = document.documentElement.clientHeight;
|
7888 |
+
scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
|
7889 |
+
scrollY = document.documentElement.scrollTop || document.body.scrollTop;
|
7890 |
+
this._pos = // should use actual width/height below
|
7891 |
+
[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
|
7892 |
+
}
|
7893 |
|
7894 |
+
// move input on screen for focus, but hidden behind dialog
|
7895 |
+
this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
|
7896 |
+
inst.settings.onSelect = onSelect;
|
7897 |
+
this._inDialog = true;
|
7898 |
+
this.dpDiv.addClass(this._dialogClass);
|
7899 |
+
this._showDatepicker(this._dialogInput[0]);
|
7900 |
+
if ($.blockUI) {
|
7901 |
+
$.blockUI(this.dpDiv);
|
7902 |
+
}
|
7903 |
+
$.data(this._dialogInput[0], PROP_NAME, inst);
|
7904 |
+
return this;
|
7905 |
},
|
7906 |
|
7907 |
+
/* Detach a datepicker from its control.
|
7908 |
+
* @param target element - the target input field or division or span
|
7909 |
+
*/
|
7910 |
+
_destroyDatepicker: function(target) {
|
7911 |
+
var nodeName,
|
7912 |
+
$target = $(target),
|
7913 |
+
inst = $.data(target, PROP_NAME);
|
7914 |
|
7915 |
+
if (!$target.hasClass(this.markerClassName)) {
|
7916 |
+
return;
|
7917 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7918 |
|
7919 |
+
nodeName = target.nodeName.toLowerCase();
|
7920 |
+
$.removeData(target, PROP_NAME);
|
7921 |
+
if (nodeName === "input") {
|
7922 |
+
inst.append.remove();
|
7923 |
+
inst.trigger.remove();
|
7924 |
+
$target.removeClass(this.markerClassName).
|
7925 |
+
unbind("focus", this._showDatepicker).
|
7926 |
+
unbind("keydown", this._doKeyDown).
|
7927 |
+
unbind("keypress", this._doKeyPress).
|
7928 |
+
unbind("keyup", this._doKeyUp);
|
7929 |
+
} else if (nodeName === "div" || nodeName === "span") {
|
7930 |
+
$target.removeClass(this.markerClassName).empty();
|
7931 |
+
}
|
7932 |
+
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7933 |
|
7934 |
+
/* Enable the date picker to a jQuery selection.
|
7935 |
+
* @param target element - the target input field or division or span
|
7936 |
+
*/
|
7937 |
+
_enableDatepicker: function(target) {
|
7938 |
+
var nodeName, inline,
|
7939 |
+
$target = $(target),
|
7940 |
+
inst = $.data(target, PROP_NAME);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7941 |
|
7942 |
+
if (!$target.hasClass(this.markerClassName)) {
|
7943 |
+
return;
|
7944 |
+
}
|
|
|
7945 |
|
7946 |
+
nodeName = target.nodeName.toLowerCase();
|
7947 |
+
if (nodeName === "input") {
|
7948 |
+
target.disabled = false;
|
7949 |
+
inst.trigger.filter("button").
|
7950 |
+
each(function() { this.disabled = false; }).end().
|
7951 |
+
filter("img").css({opacity: "1.0", cursor: ""});
|
7952 |
+
} else if (nodeName === "div" || nodeName === "span") {
|
7953 |
+
inline = $target.children("." + this._inlineClass);
|
7954 |
+
inline.children().removeClass("ui-state-disabled");
|
7955 |
+
inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
|
7956 |
+
prop("disabled", false);
|
7957 |
+
}
|
7958 |
+
this._disabledInputs = $.map(this._disabledInputs,
|
7959 |
+
function(value) { return (value === target ? null : value); }); // delete entry
|
7960 |
+
},
|
7961 |
|
7962 |
+
/* Disable the date picker to a jQuery selection.
|
7963 |
+
* @param target element - the target input field or division or span
|
7964 |
+
*/
|
7965 |
+
_disableDatepicker: function(target) {
|
7966 |
+
var nodeName, inline,
|
7967 |
+
$target = $(target),
|
7968 |
+
inst = $.data(target, PROP_NAME);
|
7969 |
|
7970 |
+
if (!$target.hasClass(this.markerClassName)) {
|
7971 |
+
return;
|
7972 |
+
}
|
|
|
|
|
|
|
|
|
7973 |
|
7974 |
+
nodeName = target.nodeName.toLowerCase();
|
7975 |
+
if (nodeName === "input") {
|
7976 |
+
target.disabled = true;
|
7977 |
+
inst.trigger.filter("button").
|
7978 |
+
each(function() { this.disabled = true; }).end().
|
7979 |
+
filter("img").css({opacity: "0.5", cursor: "default"});
|
7980 |
+
} else if (nodeName === "div" || nodeName === "span") {
|
7981 |
+
inline = $target.children("." + this._inlineClass);
|
7982 |
+
inline.children().addClass("ui-state-disabled");
|
7983 |
+
inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
|
7984 |
+
prop("disabled", true);
|
7985 |
+
}
|
7986 |
+
this._disabledInputs = $.map(this._disabledInputs,
|
7987 |
+
function(value) { return (value === target ? null : value); }); // delete entry
|
7988 |
+
this._disabledInputs[this._disabledInputs.length] = target;
|
7989 |
+
},
|
7990 |
|
7991 |
+
/* Is the first field in a jQuery collection disabled as a datepicker?
|
7992 |
+
* @param target element - the target input field or division or span
|
7993 |
+
* @return boolean - true if disabled, false if enabled
|
7994 |
+
*/
|
7995 |
+
_isDisabledDatepicker: function(target) {
|
7996 |
+
if (!target) {
|
7997 |
+
return false;
|
7998 |
+
}
|
7999 |
+
for (var i = 0; i < this._disabledInputs.length; i++) {
|
8000 |
+
if (this._disabledInputs[i] === target) {
|
8001 |
+
return true;
|
8002 |
}
|
8003 |
+
}
|
8004 |
+
return false;
|
8005 |
+
},
|
8006 |
|
8007 |
+
/* Retrieve the instance data for the target control.
|
8008 |
+
* @param target element - the target input field or division or span
|
8009 |
+
* @return object - the associated instance data
|
8010 |
+
* @throws error if a jQuery problem getting data
|
8011 |
+
*/
|
8012 |
+
_getInst: function(target) {
|
8013 |
+
try {
|
8014 |
+
return $.data(target, PROP_NAME);
|
8015 |
+
}
|
8016 |
+
catch (err) {
|
8017 |
+
throw "Missing instance data for this datepicker";
|
8018 |
}
|
8019 |
+
},
|
8020 |
|
8021 |
+
/* Update or retrieve the settings for a date picker attached to an input field or division.
|
8022 |
+
* @param target element - the target input field or division or span
|
8023 |
+
* @param name object - the new settings to update or
|
8024 |
+
* string - the name of the setting to change or retrieve,
|
8025 |
+
* when retrieving also "all" for all instance settings or
|
8026 |
+
* "defaults" for all global defaults
|
8027 |
+
* @param value any - the new value for the setting
|
8028 |
+
* (omit if above is an object or to retrieve a value)
|
8029 |
+
*/
|
8030 |
+
_optionDatepicker: function(target, name, value) {
|
8031 |
+
var settings, date, minDate, maxDate,
|
8032 |
+
inst = this._getInst(target);
|
8033 |
|
8034 |
+
if (arguments.length === 2 && typeof name === "string") {
|
8035 |
+
return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
|
8036 |
+
(inst ? (name === "all" ? $.extend({}, inst.settings) :
|
8037 |
+
this._get(inst, name)) : null));
|
8038 |
}
|
8039 |
|
8040 |
+
settings = name || {};
|
8041 |
+
if (typeof name === "string") {
|
8042 |
+
settings = {};
|
8043 |
+
settings[name] = value;
|
|
|
8044 |
}
|
8045 |
|
8046 |
+
if (inst) {
|
8047 |
+
if (this._curInst === inst) {
|
8048 |
+
this._hideDatepicker();
|
8049 |
+
}
|
|
|
|
|
|
|
8050 |
|
8051 |
+
date = this._getDateDatepicker(target, true);
|
8052 |
+
minDate = this._getMinMaxDate(inst, "min");
|
8053 |
+
maxDate = this._getMinMaxDate(inst, "max");
|
8054 |
+
extendRemove(inst.settings, settings);
|
8055 |
+
// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
|
8056 |
+
if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
|
8057 |
+
inst.settings.minDate = this._formatDate(inst, minDate);
|
8058 |
+
}
|
8059 |
+
if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
|
8060 |
+
inst.settings.maxDate = this._formatDate(inst, maxDate);
|
8061 |
+
}
|
8062 |
+
if ( "disabled" in settings ) {
|
8063 |
+
if ( settings.disabled ) {
|
8064 |
+
this._disableDatepicker(target);
|
8065 |
+
} else {
|
8066 |
+
this._enableDatepicker(target);
|
8067 |
}
|
8068 |
+
}
|
8069 |
+
this._attachments($(target), inst);
|
8070 |
+
this._autoSize(inst);
|
8071 |
+
this._setDate(inst, date);
|
8072 |
+
this._updateAlternate(inst);
|
8073 |
+
this._updateDatepicker(inst);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8074 |
}
|
8075 |
+
},
|
8076 |
|
8077 |
+
// change method deprecated
|
8078 |
+
_changeDatepicker: function(target, name, value) {
|
8079 |
+
this._optionDatepicker(target, name, value);
|
8080 |
+
},
|
8081 |
+
|
8082 |
+
/* Redraw the date picker attached to an input field or division.
|
8083 |
+
* @param target element - the target input field or division or span
|
8084 |
+
*/
|
8085 |
+
_refreshDatepicker: function(target) {
|
8086 |
+
var inst = this._getInst(target);
|
8087 |
+
if (inst) {
|
8088 |
+
this._updateDatepicker(inst);
|
8089 |
}
|
8090 |
+
},
|
8091 |
|
8092 |
+
/* Set the dates for a jQuery selection.
|
8093 |
+
* @param target element - the target input field or division or span
|
8094 |
+
* @param date Date - the new date
|
8095 |
+
*/
|
8096 |
+
_setDateDatepicker: function(target, date) {
|
8097 |
+
var inst = this._getInst(target);
|
8098 |
+
if (inst) {
|
8099 |
+
this._setDate(inst, date);
|
8100 |
+
this._updateDatepicker(inst);
|
8101 |
+
this._updateAlternate(inst);
|
8102 |
}
|
8103 |
+
},
|
8104 |
|
8105 |
+
/* Get the date(s) for the first entry in a jQuery selection.
|
8106 |
+
* @param target element - the target input field or division or span
|
8107 |
+
* @param noDefault boolean - true if no default date is to be used
|
8108 |
+
* @return Date - the current date
|
8109 |
+
*/
|
8110 |
+
_getDateDatepicker: function(target, noDefault) {
|
8111 |
+
var inst = this._getInst(target);
|
8112 |
+
if (inst && !inst.inline) {
|
8113 |
+
this._setDateFromField(inst, noDefault);
|
8114 |
+
}
|
8115 |
+
return (inst ? this._getDate(inst) : null);
|
8116 |
+
},
|
|
|
|
|
|
|
8117 |
|
8118 |
+
/* Handle keystrokes. */
|
8119 |
+
_doKeyDown: function(event) {
|
8120 |
+
var onSelect, dateStr, sel,
|
8121 |
+
inst = $.datepicker._getInst(event.target),
|
8122 |
+
handled = true,
|
8123 |
+
isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8124 |
|
8125 |
+
inst._keyEvent = true;
|
8126 |
+
if ($.datepicker._datepickerShowing) {
|
8127 |
+
switch (event.keyCode) {
|
8128 |
+
case 9: $.datepicker._hideDatepicker();
|
8129 |
+
handled = false;
|
8130 |
+
break; // hide on tab out
|
8131 |
+
case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
|
8132 |
+
$.datepicker._currentClass + ")", inst.dpDiv);
|
8133 |
+
if (sel[0]) {
|
8134 |
+
$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
|
8135 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8136 |
|
8137 |
+
onSelect = $.datepicker._get(inst, "onSelect");
|
8138 |
+
if (onSelect) {
|
8139 |
+
dateStr = $.datepicker._formatDate(inst);
|
8140 |
|
8141 |
+
// trigger custom callback
|
8142 |
+
onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
|
8143 |
+
} else {
|
8144 |
+
$.datepicker._hideDatepicker();
|
8145 |
+
}
|
8146 |
|
8147 |
+
return false; // don't submit the form
|
8148 |
+
case 27: $.datepicker._hideDatepicker();
|
8149 |
+
break; // hide on escape
|
8150 |
+
case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
|
8151 |
+
-$.datepicker._get(inst, "stepBigMonths") :
|
8152 |
+
-$.datepicker._get(inst, "stepMonths")), "M");
|
8153 |
+
break; // previous month/year on page up/+ ctrl
|
8154 |
+
case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
|
8155 |
+
+$.datepicker._get(inst, "stepBigMonths") :
|
8156 |
+
+$.datepicker._get(inst, "stepMonths")), "M");
|
8157 |
+
break; // next month/year on page down/+ ctrl
|
8158 |
+
case 35: if (event.ctrlKey || event.metaKey) {
|
8159 |
+
$.datepicker._clearDate(event.target);
|
8160 |
+
}
|
8161 |
+
handled = event.ctrlKey || event.metaKey;
|
8162 |
+
break; // clear on ctrl or command +end
|
8163 |
+
case 36: if (event.ctrlKey || event.metaKey) {
|
8164 |
+
$.datepicker._gotoToday(event.target);
|
8165 |
+
}
|
8166 |
+
handled = event.ctrlKey || event.metaKey;
|
8167 |
+
break; // current on ctrl or command +home
|
8168 |
+
case 37: if (event.ctrlKey || event.metaKey) {
|
8169 |
+
$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
|
8170 |
+
}
|
8171 |
+
handled = event.ctrlKey || event.metaKey;
|
8172 |
+
// -1 day on ctrl or command +left
|
8173 |
+
if (event.originalEvent.altKey) {
|
8174 |
+
$.datepicker._adjustDate(event.target, (event.ctrlKey ?
|
8175 |
+
-$.datepicker._get(inst, "stepBigMonths") :
|
8176 |
+
-$.datepicker._get(inst, "stepMonths")), "M");
|
8177 |
+
}
|
8178 |
+
// next month/year on alt +left on Mac
|
8179 |
+
break;
|
8180 |
+
case 38: if (event.ctrlKey || event.metaKey) {
|
8181 |
+
$.datepicker._adjustDate(event.target, -7, "D");
|
8182 |
+
}
|
8183 |
+
handled = event.ctrlKey || event.metaKey;
|
8184 |
+
break; // -1 week on ctrl or command +up
|
8185 |
+
case 39: if (event.ctrlKey || event.metaKey) {
|
8186 |
+
$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
|
8187 |
+
}
|
8188 |
+
handled = event.ctrlKey || event.metaKey;
|
8189 |
+
// +1 day on ctrl or command +right
|
8190 |
+
if (event.originalEvent.altKey) {
|
8191 |
+
$.datepicker._adjustDate(event.target, (event.ctrlKey ?
|
8192 |
+
+$.datepicker._get(inst, "stepBigMonths") :
|
8193 |
+
+$.datepicker._get(inst, "stepMonths")), "M");
|
8194 |
+
}
|
8195 |
+
// next month/year on alt +right
|
8196 |
+
break;
|
8197 |
+
case 40: if (event.ctrlKey || event.metaKey) {
|
8198 |
+
$.datepicker._adjustDate(event.target, +7, "D");
|
8199 |
+
}
|
8200 |
+
handled = event.ctrlKey || event.metaKey;
|
8201 |
+
break; // +1 week on ctrl or command +down
|
8202 |
+
default: handled = false;
|
8203 |
+
}
|
8204 |
+
} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
|
8205 |
+
$.datepicker._showDatepicker(this);
|
8206 |
+
} else {
|
8207 |
+
handled = false;
|
8208 |
+
}
|
8209 |
|
8210 |
+
if (handled) {
|
8211 |
+
event.preventDefault();
|
8212 |
+
event.stopPropagation();
|
8213 |
+
}
|
8214 |
+
},
|
8215 |
|
8216 |
+
/* Filter entered characters - based on date format. */
|
8217 |
+
_doKeyPress: function(event) {
|
8218 |
+
var chars, chr,
|
8219 |
+
inst = $.datepicker._getInst(event.target);
|
8220 |
|
8221 |
+
if ($.datepicker._get(inst, "constrainInput")) {
|
8222 |
+
chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
|
8223 |
+
chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
|
8224 |
+
return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
|
8225 |
+
}
|
8226 |
+
},
|
8227 |
|
8228 |
+
/* Synchronise manual entry and field/alternate field. */
|
8229 |
+
_doKeyUp: function(event) {
|
8230 |
+
var date,
|
8231 |
+
inst = $.datepicker._getInst(event.target);
|
8232 |
|
8233 |
+
if (inst.input.val() !== inst.lastVal) {
|
8234 |
+
try {
|
8235 |
+
date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
|
8236 |
+
(inst.input ? inst.input.val() : null),
|
8237 |
+
$.datepicker._getFormatConfig(inst));
|
8238 |
|
8239 |
+
if (date) { // only if valid
|
8240 |
+
$.datepicker._setDateFromField(inst);
|
8241 |
+
$.datepicker._updateAlternate(inst);
|
8242 |
+
$.datepicker._updateDatepicker(inst);
|
8243 |
}
|
8244 |
}
|
8245 |
+
catch (err) {
|
|
|
|
|
8246 |
}
|
8247 |
+
}
|
8248 |
+
return true;
|
8249 |
+
},
|
8250 |
|
8251 |
+
/* Pop-up the date picker for a given input field.
|
8252 |
+
* If false returned from beforeShow event handler do not show.
|
8253 |
+
* @param input element - the input field attached to the date picker or
|
8254 |
+
* event - if triggered by focus
|
8255 |
+
*/
|
8256 |
+
_showDatepicker: function(input) {
|
8257 |
+
input = input.target || input;
|
8258 |
+
if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
|
8259 |
+
input = $("input", input.parentNode)[0];
|
8260 |
+
}
|
|
|
|
|
|
|
|
|
|
|
8261 |
|
8262 |
+
if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
|
8263 |
+
return;
|
8264 |
+
}
|
|
|
|
|
|
|
|
|
|
|
8265 |
|
8266 |
+
var inst, beforeShow, beforeShowSettings, isFixed,
|
8267 |
+
offset, showAnim, duration;
|
|
|
|
|
|
|
8268 |
|
8269 |
+
inst = $.datepicker._getInst(input);
|
8270 |
+
if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
|
8271 |
+
$.datepicker._curInst.dpDiv.stop(true, true);
|
8272 |
+
if ( inst && $.datepicker._datepickerShowing ) {
|
8273 |
+
$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
|
8274 |
+
}
|
8275 |
}
|
8276 |
|
8277 |
+
beforeShow = $.datepicker._get(inst, "beforeShow");
|
8278 |
+
beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
|
8279 |
+
if(beforeShowSettings === false){
|
8280 |
+
return;
|
8281 |
+
}
|
8282 |
+
extendRemove(inst.settings, beforeShowSettings);
|
8283 |
|
8284 |
+
inst.lastVal = null;
|
8285 |
+
$.datepicker._lastInput = input;
|
8286 |
+
$.datepicker._setDateFromField(inst);
|
8287 |
|
8288 |
+
if ($.datepicker._inDialog) { // hide cursor
|
8289 |
+
input.value = "";
|
8290 |
+
}
|
8291 |
+
if (!$.datepicker._pos) { // position below input
|
8292 |
+
$.datepicker._pos = $.datepicker._findPos(input);
|
8293 |
+
$.datepicker._pos[1] += input.offsetHeight; // add the height
|
8294 |
+
}
|
8295 |
|
8296 |
+
isFixed = false;
|
8297 |
+
$(input).parents().each(function() {
|
8298 |
+
isFixed |= $(this).css("position") === "fixed";
|
8299 |
+
return !isFixed;
|
8300 |
+
});
|
8301 |
|
8302 |
+
offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
|
8303 |
+
$.datepicker._pos = null;
|
8304 |
+
//to avoid flashes on Firefox
|
8305 |
+
inst.dpDiv.empty();
|
8306 |
+
// determine sizing offscreen
|
8307 |
+
inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
|
8308 |
+
$.datepicker._updateDatepicker(inst);
|
8309 |
+
// fix width for dynamic number of date pickers
|
8310 |
+
// and adjust position before showing
|
8311 |
+
offset = $.datepicker._checkOffset(inst, offset, isFixed);
|
8312 |
+
inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
|
8313 |
+
"static" : (isFixed ? "fixed" : "absolute")), display: "none",
|
8314 |
+
left: offset.left + "px", top: offset.top + "px"});
|
8315 |
|
8316 |
+
if (!inst.inline) {
|
8317 |
+
showAnim = $.datepicker._get(inst, "showAnim");
|
8318 |
+
duration = $.datepicker._get(inst, "duration");
|
8319 |
+
inst.dpDiv.zIndex($(input).zIndex()+1);
|
8320 |
+
$.datepicker._datepickerShowing = true;
|
|
|
|
|
|
|
|
|
|
|
8321 |
|
8322 |
+
if ( $.effects && $.effects.effect[ showAnim ] ) {
|
8323 |
+
inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
|
|
|
8324 |
} else {
|
8325 |
+
inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8326 |
}
|
|
|
8327 |
|
8328 |
+
if (inst.input.is(":visible") && !inst.input.is(":disabled")) {
|
8329 |
+
inst.input.focus();
|
8330 |
+
}
|
8331 |
+
$.datepicker._curInst = inst;
|
8332 |
}
|
|
|
|
|
8333 |
},
|
8334 |
|
8335 |
+
/* Generate the date picker content. */
|
8336 |
+
_updateDatepicker: function(inst) {
|
8337 |
+
this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
|
8338 |
+
instActive = inst; // for delegate hover events
|
8339 |
+
inst.dpDiv.empty().append(this._generateHTML(inst));
|
8340 |
+
this._attachHandlers(inst);
|
8341 |
+
inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
|
8342 |
+
|
8343 |
+
var origyearshtml,
|
8344 |
+
numMonths = this._getNumberOfMonths(inst),
|
8345 |
+
cols = numMonths[1],
|
8346 |
+
width = 17;
|
8347 |
+
|
8348 |
+
inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
|
8349 |
+
if (cols > 1) {
|
8350 |
+
inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
|
8351 |
+
}
|
8352 |
+
inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
|
8353 |
+
"Class"]("ui-datepicker-multi");
|
8354 |
+
inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
|
8355 |
+
"Class"]("ui-datepicker-rtl");
|
8356 |
+
|
8357 |
+
// #6694 - don't focus the input if it's already focused
|
8358 |
+
// this breaks the change event in IE
|
8359 |
+
if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
|
8360 |
+
inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) {
|
8361 |
+
inst.input.focus();
|
8362 |
}
|
|
|
8363 |
|
8364 |
+
// deffered render of the years select (to avoid flashes on Firefox)
|
8365 |
+
if( inst.yearshtml ){
|
8366 |
+
origyearshtml = inst.yearshtml;
|
8367 |
+
setTimeout(function(){
|
8368 |
+
//assure that inst.yearshtml didn't change.
|
8369 |
+
if( origyearshtml === inst.yearshtml && inst.yearshtml ){
|
8370 |
+
inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
|
8371 |
+
}
|
8372 |
+
origyearshtml = inst.yearshtml = null;
|
8373 |
+
}, 0);
|
8374 |
}
|
8375 |
+
},
|
8376 |
|
8377 |
+
/* Retrieve the size of left and top borders for an element.
|
8378 |
+
* @param elem (jQuery object) the element of interest
|
8379 |
+
* @return (number[2]) the left and top borders
|
8380 |
+
*/
|
8381 |
+
_getBorders: function(elem) {
|
8382 |
+
var convert = function(value) {
|
8383 |
+
return {thin: 1, medium: 2, thick: 3}[value] || value;
|
8384 |
+
};
|
8385 |
+
return [parseFloat(convert(elem.css("border-left-width"))),
|
8386 |
+
parseFloat(convert(elem.css("border-top-width")))];
|
8387 |
+
},
|
8388 |
|
8389 |
+
/* Check positioning to remain on screen. */
|
8390 |
+
_checkOffset: function(inst, offset, isFixed) {
|
8391 |
+
var dpWidth = inst.dpDiv.outerWidth(),
|
8392 |
+
dpHeight = inst.dpDiv.outerHeight(),
|
8393 |
+
inputWidth = inst.input ? inst.input.outerWidth() : 0,
|
8394 |
+
inputHeight = inst.input ? inst.input.outerHeight() : 0,
|
8395 |
+
viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
|
8396 |
+
viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
|
8397 |
|
8398 |
+
offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
|
8399 |
+
offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
|
8400 |
+
offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
|
|
|
|
|
|
|
|
|
8401 |
|
8402 |
+
// now check if datepicker is showing outside window viewport - move to a better place if so.
|
8403 |
+
offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
|
8404 |
+
Math.abs(offset.left + dpWidth - viewWidth) : 0);
|
8405 |
+
offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
|
8406 |
+
Math.abs(dpHeight + inputHeight) : 0);
|
8407 |
|
8408 |
+
return offset;
|
|
|
8409 |
},
|
8410 |
|
8411 |
+
/* Find an object's position on the screen. */
|
8412 |
+
_findPos: function(obj) {
|
8413 |
+
var position,
|
8414 |
+
inst = this._getInst(obj),
|
8415 |
+
isRTL = this._get(inst, "isRTL");
|
8416 |
|
8417 |
+
while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
|
8418 |
+
obj = obj[isRTL ? "previousSibling" : "nextSibling"];
|
|
|
|
|
8419 |
}
|
8420 |
|
8421 |
+
position = $(obj).offset();
|
8422 |
+
return [position.left, position.top];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8423 |
},
|
8424 |
|
8425 |
+
/* Hide the date picker from view.
|
8426 |
+
* @param input element - the input field attached to the date picker
|
8427 |
+
*/
|
8428 |
+
_hideDatepicker: function(input) {
|
8429 |
+
var showAnim, duration, postProcess, onClose,
|
8430 |
+
inst = this._curInst;
|
8431 |
+
|
8432 |
+
if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
|
8433 |
return;
|
8434 |
}
|
8435 |
|
8436 |
+
if (this._datepickerShowing) {
|
8437 |
+
showAnim = this._get(inst, "showAnim");
|
8438 |
+
duration = this._get(inst, "duration");
|
8439 |
+
postProcess = function() {
|
8440 |
+
$.datepicker._tidyDialog(inst);
|
8441 |
+
};
|
|
|
|
|
8442 |
|
8443 |
+
// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
|
8444 |
+
if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
|
8445 |
+
inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
|
8446 |
+
} else {
|
8447 |
+
inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
|
8448 |
+
(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
|
8449 |
+
}
|
8450 |
+
|
8451 |
+
if (!showAnim) {
|
8452 |
+
postProcess();
|
8453 |
+
}
|
8454 |
+
this._datepickerShowing = false;
|
8455 |
|
8456 |
+
onClose = this._get(inst, "onClose");
|
8457 |
+
if (onClose) {
|
8458 |
+
onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
|
8459 |
+
}
|
8460 |
|
8461 |
+
this._lastInput = null;
|
8462 |
+
if (this._inDialog) {
|
8463 |
+
this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
|
8464 |
+
if ($.blockUI) {
|
8465 |
+
$.unblockUI();
|
8466 |
+
$("body").append(this.dpDiv);
|
8467 |
+
}
|
8468 |
+
}
|
8469 |
+
this._inDialog = false;
|
8470 |
}
|
8471 |
+
},
|
8472 |
|
8473 |
+
/* Tidy up after a dialog display. */
|
8474 |
+
_tidyDialog: function(inst) {
|
8475 |
+
inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
|
8476 |
},
|
8477 |
|
8478 |
+
/* Close date picker if clicked elsewhere. */
|
8479 |
+
_checkExternalClick: function(event) {
|
8480 |
+
if (!$.datepicker._curInst) {
|
8481 |
+
return;
|
|
|
|
|
|
|
|
|
8482 |
}
|
|
|
|
|
|
|
8483 |
|
8484 |
+
var $target = $(event.target),
|
8485 |
+
inst = $.datepicker._getInst($target[0]);
|
8486 |
+
|
8487 |
+
if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
|
8488 |
+
$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
|
8489 |
+
!$target.hasClass($.datepicker.markerClassName) &&
|
8490 |
+
!$target.closest("." + $.datepicker._triggerClass).length &&
|
8491 |
+
$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
|
8492 |
+
( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
|
8493 |
+
$.datepicker._hideDatepicker();
|
8494 |
+
}
|
8495 |
+
},
|
8496 |
|
8497 |
+
/* Adjust one of the date sub-fields. */
|
8498 |
+
_adjustDate: function(id, offset, period) {
|
8499 |
+
var target = $(id),
|
8500 |
+
inst = this._getInst(target[0]);
|
8501 |
|
8502 |
+
if (this._isDisabledDatepicker(target[0])) {
|
|
|
|
|
8503 |
return;
|
8504 |
}
|
8505 |
+
this._adjustInstDate(inst, offset +
|
8506 |
+
(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
|
8507 |
+
period);
|
8508 |
+
this._updateDatepicker(inst);
|
8509 |
+
},
|
8510 |
|
8511 |
+
/* Action for current link. */
|
8512 |
+
_gotoToday: function(id) {
|
8513 |
+
var date,
|
8514 |
+
target = $(id),
|
8515 |
+
inst = this._getInst(target[0]);
|
8516 |
|
8517 |
+
if (this._get(inst, "gotoCurrent") && inst.currentDay) {
|
8518 |
+
inst.selectedDay = inst.currentDay;
|
8519 |
+
inst.drawMonth = inst.selectedMonth = inst.currentMonth;
|
8520 |
+
inst.drawYear = inst.selectedYear = inst.currentYear;
|
8521 |
+
} else {
|
8522 |
+
date = new Date();
|
8523 |
+
inst.selectedDay = date.getDate();
|
8524 |
+
inst.drawMonth = inst.selectedMonth = date.getMonth();
|
8525 |
+
inst.drawYear = inst.selectedYear = date.getFullYear();
|
8526 |
}
|
8527 |
+
this._notifyChange(inst);
|
8528 |
+
this._adjustDate(target);
|
8529 |
+
},
|
8530 |
|
8531 |
+
/* Action for selecting a new month/year. */
|
8532 |
+
_selectMonthYear: function(id, select, period) {
|
8533 |
+
var target = $(id),
|
8534 |
+
inst = this._getInst(target[0]);
|
8535 |
|
8536 |
+
inst["selected" + (period === "M" ? "Month" : "Year")] =
|
8537 |
+
inst["draw" + (period === "M" ? "Month" : "Year")] =
|
8538 |
+
parseInt(select.options[select.selectedIndex].value,10);
|
8539 |
|
8540 |
+
this._notifyChange(inst);
|
8541 |
+
this._adjustDate(target);
|
8542 |
+
},
|
8543 |
|
8544 |
+
/* Action for selecting a day. */
|
8545 |
+
_selectDay: function(id, month, year, td) {
|
8546 |
+
var inst,
|
8547 |
+
target = $(id);
|
|
|
|
|
|
|
|
|
|
|
8548 |
|
8549 |
+
if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
|
8550 |
+
return;
|
8551 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8552 |
|
8553 |
+
inst = this._getInst(target[0]);
|
8554 |
+
inst.selectedDay = inst.currentDay = $("a", td).html();
|
8555 |
+
inst.selectedMonth = inst.currentMonth = month;
|
8556 |
+
inst.selectedYear = inst.currentYear = year;
|
8557 |
+
this._selectDate(id, this._formatDate(inst,
|
8558 |
+
inst.currentDay, inst.currentMonth, inst.currentYear));
|
8559 |
+
},
|
8560 |
|
8561 |
+
/* Erase the input field and hide the date picker. */
|
8562 |
+
_clearDate: function(id) {
|
8563 |
+
var target = $(id);
|
8564 |
+
this._selectDate(target, "");
|
8565 |
},
|
8566 |
|
8567 |
+
/* Update the input field with the selected date. */
|
8568 |
+
_selectDate: function(id, dateStr) {
|
8569 |
+
var onSelect,
|
8570 |
+
target = $(id),
|
8571 |
+
inst = this._getInst(target[0]);
|
8572 |
|
8573 |
+
dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
|
8574 |
+
if (inst.input) {
|
8575 |
+
inst.input.val(dateStr);
|
8576 |
+
}
|
8577 |
+
this._updateAlternate(inst);
|
8578 |
|
8579 |
+
onSelect = this._get(inst, "onSelect");
|
8580 |
+
if (onSelect) {
|
8581 |
+
onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
|
8582 |
+
} else if (inst.input) {
|
8583 |
+
inst.input.trigger("change"); // fire the change event
|
8584 |
}
|
8585 |
|
8586 |
+
if (inst.inline){
|
8587 |
+
this._updateDatepicker(inst);
|
8588 |
+
} else {
|
8589 |
+
this._hideDatepicker();
|
8590 |
+
this._lastInput = inst.input[0];
|
8591 |
+
if (typeof(inst.input[0]) !== "object") {
|
8592 |
+
inst.input.focus(); // restore focus
|
8593 |
+
}
|
8594 |
+
this._lastInput = null;
|
8595 |
+
}
|
8596 |
},
|
8597 |
|
8598 |
+
/* Update any alternate field to synchronise with the main field. */
|
8599 |
+
_updateAlternate: function(inst) {
|
8600 |
+
var altFormat, date, dateStr,
|
8601 |
+
altField = this._get(inst, "altField");
|
8602 |
+
|
8603 |
+
if (altField) { // update alternate field too
|
8604 |
+
altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
|
8605 |
+
date = this._getDate(inst);
|
8606 |
+
dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
|
8607 |
+
$(altField).each(function() { $(this).val(dateStr); });
|
8608 |
+
}
|
8609 |
},
|
8610 |
|
8611 |
+
/* Set as beforeShowDay function to prevent selection of weekends.
|
8612 |
+
* @param date Date - the date to customise
|
8613 |
+
* @return [boolean, string] - is this date selectable?, what is its CSS class?
|
8614 |
+
*/
|
8615 |
+
noWeekends: function(date) {
|
8616 |
+
var day = date.getDay();
|
8617 |
+
return [(day > 0 && day < 6), ""];
|
8618 |
+
},
|
8619 |
|
8620 |
+
/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
|
8621 |
+
* @param date Date - the date to get the week for
|
8622 |
+
* @return number - the number of the week within the year that contains this date
|
8623 |
+
*/
|
8624 |
+
iso8601Week: function(date) {
|
8625 |
+
var time,
|
8626 |
+
checkDate = new Date(date.getTime());
|
8627 |
|
8628 |
+
// Find Thursday of this week starting on Monday
|
8629 |
+
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
|
|
|
8630 |
|
8631 |
+
time = checkDate.getTime();
|
8632 |
+
checkDate.setMonth(0); // Compare with Jan 1
|
8633 |
+
checkDate.setDate(1);
|
8634 |
+
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
|
8635 |
+
},
|
|
|
|
|
|
|
8636 |
|
8637 |
+
/* Parse a string value into a date object.
|
8638 |
+
* See formatDate below for the possible formats.
|
8639 |
+
*
|
8640 |
+
* @param format string - the expected format of the date
|
8641 |
+
* @param value string - the date in the above format
|
8642 |
+
* @param settings Object - attributes include:
|
8643 |
+
* shortYearCutoff number - the cutoff year for determining the century (optional)
|
8644 |
+
* dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
|
8645 |
+
* dayNames string[7] - names of the days from Sunday (optional)
|
8646 |
+
* monthNamesShort string[12] - abbreviated names of the months (optional)
|
8647 |
+
* monthNames string[12] - names of the months (optional)
|
8648 |
+
* @return Date - the extracted date value or null if value is blank
|
8649 |
+
*/
|
8650 |
+
parseDate: function (format, value, settings) {
|
8651 |
+
if (format == null || value == null) {
|
8652 |
+
throw "Invalid arguments";
|
8653 |
+
}
|
8654 |
+
|
8655 |
+
value = (typeof value === "object" ? value.toString() : value + "");
|
8656 |
+
if (value === "") {
|
8657 |
+
return null;
|
8658 |
+
}
|
8659 |
+
|
8660 |
+
var iFormat, dim, extra,
|
8661 |
+
iValue = 0,
|
8662 |
+
shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
|
8663 |
+
shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
|
8664 |
+
new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
|
8665 |
+
dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
|
8666 |
+
dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
|
8667 |
+
monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
|
8668 |
+
monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
|
8669 |
+
year = -1,
|
8670 |
+
month = -1,
|
8671 |
+
day = -1,
|
8672 |
+
doy = -1,
|
8673 |
+
literal = false,
|
8674 |
+
date,
|
8675 |
+
// Check whether a format character is doubled
|
8676 |
+
lookAhead = function(match) {
|
8677 |
+
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
|
8678 |
+
if (matches) {
|
8679 |
+
iFormat++;
|
8680 |
+
}
|
8681 |
+
return matches;
|
8682 |
+
},
|
8683 |
+
// Extract a number from the string value
|
8684 |
+
getNumber = function(match) {
|
8685 |
+
var isDoubled = lookAhead(match),
|
8686 |
+
size = (match === "@" ? 14 : (match === "!" ? 20 :
|
8687 |
+
(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
|
8688 |
+
digits = new RegExp("^\\d{1," + size + "}"),
|
8689 |
+
num = value.substring(iValue).match(digits);
|
8690 |
+
if (!num) {
|
8691 |
+
throw "Missing number at position " + iValue;
|
8692 |
+
}
|
8693 |
+
iValue += num[0].length;
|
8694 |
+
return parseInt(num[0], 10);
|
8695 |
+
},
|
8696 |
+
// Extract a name from the string value and convert to an index
|
8697 |
+
getName = function(match, shortNames, longNames) {
|
8698 |
+
var index = -1,
|
8699 |
+
names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
|
8700 |
+
return [ [k, v] ];
|
8701 |
+
}).sort(function (a, b) {
|
8702 |
+
return -(a[1].length - b[1].length);
|
8703 |
+
});
|
8704 |
+
|
8705 |
+
$.each(names, function (i, pair) {
|
8706 |
+
var name = pair[1];
|
8707 |
+
if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
|
8708 |
+
index = pair[0];
|
8709 |
+
iValue += name.length;
|
8710 |
+
return false;
|
8711 |
+
}
|
8712 |
+
});
|
8713 |
+
if (index !== -1) {
|
8714 |
+
return index + 1;
|
8715 |
+
} else {
|
8716 |
+
throw "Unknown name at position " + iValue;
|
8717 |
+
}
|
8718 |
+
},
|
8719 |
+
// Confirm that a literal character matches the string value
|
8720 |
+
checkLiteral = function() {
|
8721 |
+
if (value.charAt(iValue) !== format.charAt(iFormat)) {
|
8722 |
+
throw "Unexpected literal at position " + iValue;
|
8723 |
+
}
|
8724 |
+
iValue++;
|
8725 |
+
};
|
8726 |
|
8727 |
+
for (iFormat = 0; iFormat < format.length; iFormat++) {
|
8728 |
+
if (literal) {
|
8729 |
+
if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
|
8730 |
+
literal = false;
|
8731 |
+
} else {
|
8732 |
+
checkLiteral();
|
8733 |
+
}
|
8734 |
+
} else {
|
8735 |
+
switch (format.charAt(iFormat)) {
|
8736 |
+
case "d":
|
8737 |
+
day = getNumber("d");
|
8738 |
+
break;
|
8739 |
+
case "D":
|
8740 |
+
getName("D", dayNamesShort, dayNames);
|
8741 |
+
break;
|
8742 |
+
case "o":
|
8743 |
+
doy = getNumber("o");
|
8744 |
+
break;
|
8745 |
+
case "m":
|
8746 |
+
month = getNumber("m");
|
8747 |
+
break;
|
8748 |
+
case "M":
|
8749 |
+
month = getName("M", monthNamesShort, monthNames);
|
8750 |
+
break;
|
8751 |
+
case "y":
|
8752 |
+
year = getNumber("y");
|
8753 |
+
break;
|
8754 |
+
case "@":
|
8755 |
+
date = new Date(getNumber("@"));
|
8756 |
+
year = date.getFullYear();
|
8757 |
+
month = date.getMonth() + 1;
|
8758 |
+
day = date.getDate();
|
8759 |
+
break;
|
8760 |
+
case "!":
|
8761 |
+
date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
|
8762 |
+
year = date.getFullYear();
|
8763 |
+
month = date.getMonth() + 1;
|
8764 |
+
day = date.getDate();
|
8765 |
+
break;
|
8766 |
+
case "'":
|
8767 |
+
if (lookAhead("'")){
|
8768 |
+
checkLiteral();
|
8769 |
+
} else {
|
8770 |
+
literal = true;
|
8771 |
+
}
|
8772 |
+
break;
|
8773 |
+
default:
|
8774 |
+
checkLiteral();
|
8775 |
}
|
8776 |
}
|
8777 |
+
}
|
|
|
|
|
|
|
8778 |
|
8779 |
+
if (iValue < value.length){
|
8780 |
+
extra = value.substr(iValue);
|
8781 |
+
if (!/^\s+/.test(extra)) {
|
8782 |
+
throw "Extra/unparsed characters found in date: " + extra;
|
8783 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8784 |
}
|
8785 |
|
8786 |
+
if (year === -1) {
|
8787 |
+
year = new Date().getFullYear();
|
8788 |
+
} else if (year < 100) {
|
8789 |
+
year += new Date().getFullYear() - new Date().getFullYear() % 100 +
|
8790 |
+
(year <= shortYearCutoff ? 0 : -100);
|
8791 |
+
}
|
8792 |
|
8793 |
+
if (doy > -1) {
|
8794 |
+
month = 1;
|
8795 |
+
day = doy;
|
8796 |
+
do {
|
8797 |
+
dim = this._getDaysInMonth(year, month - 1);
|
8798 |
+
if (day <= dim) {
|
8799 |
+
break;
|
8800 |
+
}
|
8801 |
+
month++;
|
8802 |
+
day -= dim;
|
8803 |
+
} while (true);
|
8804 |
+
}
|
|
|
|
|
8805 |
|
8806 |
+
date = this._daylightSavingAdjust(new Date(year, month - 1, day));
|
8807 |
+
if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
|
8808 |
+
throw "Invalid date"; // E.g. 31/02/00
|
8809 |
+
}
|
8810 |
+
return date;
|
8811 |
+
},
|
8812 |
|
8813 |
+
/* Standard date formats. */
|
8814 |
+
ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
|
8815 |
+
COOKIE: "D, dd M yy",
|
8816 |
+
ISO_8601: "yy-mm-dd",
|
8817 |
+
RFC_822: "D, d M y",
|
8818 |
+
RFC_850: "DD, dd-M-y",
|
8819 |
+
RFC_1036: "D, d M y",
|
8820 |
+
RFC_1123: "D, d M yy",
|
8821 |
+
RFC_2822: "D, d M yy",
|
8822 |
+
RSS: "D, d M y", // RFC 822
|
8823 |
+
TICKS: "!",
|
8824 |
+
TIMESTAMP: "@",
|
8825 |
+
W3C: "yy-mm-dd", // ISO 8601
|
8826 |
|
8827 |
+
_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
|
8828 |
+
Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
|
|
|
|
|
8829 |
|
8830 |
+
/* Format a date object into a string value.
|
8831 |
+
* The format can be combinations of the following:
|
8832 |
+
* d - day of month (no leading zero)
|
8833 |
+
* dd - day of month (two digit)
|
8834 |
+
* o - day of year (no leading zeros)
|
8835 |
+
* oo - day of year (three digit)
|
8836 |
+
* D - day name short
|
8837 |
+
* DD - day name long
|
8838 |
+
* m - month of year (no leading zero)
|
8839 |
+
* mm - month of year (two digit)
|
8840 |
+
* M - month name short
|
8841 |
+
* MM - month name long
|
8842 |
+
* y - year (two digit)
|
8843 |
+
* yy - year (four digit)
|
8844 |
+
* @ - Unix timestamp (ms since 01/01/1970)
|
8845 |
+
* ! - Windows ticks (100ns since 01/01/0001)
|
8846 |
+
* "..." - literal text
|
8847 |
+
* '' - single quote
|
8848 |
+
*
|
8849 |
+
* @param format string - the desired format of the date
|
8850 |
+
* @param date Date - the date value to format
|
8851 |
+
* @param settings Object - attributes include:
|
8852 |
+
* dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
|
8853 |
+
* dayNames string[7] - names of the days from Sunday (optional)
|
8854 |
+
* monthNamesShort string[12] - abbreviated names of the months (optional)
|
8855 |
+
* monthNames string[12] - names of the months (optional)
|
8856 |
+
* @return string - the date in the above format
|
8857 |
+
*/
|
8858 |
+
formatDate: function (format, date, settings) {
|
8859 |
+
if (!date) {
|
8860 |
+
return "";
|
8861 |
+
}
|
8862 |
+
|
8863 |
+
var iFormat,
|
8864 |
+
dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
|
8865 |
+
dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
|
8866 |
+
monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
|
8867 |
+
monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
|
8868 |
+
// Check whether a format character is doubled
|
8869 |
+
lookAhead = function(match) {
|
8870 |
+
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
|
8871 |
+
if (matches) {
|
8872 |
+
iFormat++;
|
8873 |
+
}
|
8874 |
+
return matches;
|
8875 |
+
},
|
8876 |
+
// Format a number, with leading zero if necessary
|
8877 |
+
formatNumber = function(match, value, len) {
|
8878 |
+
var num = "" + value;
|
8879 |
+
if (lookAhead(match)) {
|
8880 |
+
while (num.length < len) {
|
8881 |
+
num = "0" + num;
|
8882 |
+
}
|
8883 |
+
}
|
8884 |
+
return num;
|
8885 |
+
},
|
8886 |
+
// Format a name, short or long as requested
|
8887 |
+
formatName = function(match, value, shortNames, longNames) {
|
8888 |
+
return (lookAhead(match) ? longNames[value] : shortNames[value]);
|
8889 |
+
},
|
8890 |
+
output = "",
|
8891 |
+
literal = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8892 |
|
8893 |
+
if (date) {
|
8894 |
+
for (iFormat = 0; iFormat < format.length; iFormat++) {
|
8895 |
+
if (literal) {
|
8896 |
+
if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
|
8897 |
+
literal = false;
|
8898 |
+
} else {
|
8899 |
+
output += format.charAt(iFormat);
|
8900 |
+
}
|
8901 |
+
} else {
|
8902 |
+
switch (format.charAt(iFormat)) {
|
8903 |
+
case "d":
|
8904 |
+
output += formatNumber("d", date.getDate(), 2);
|
8905 |
+
break;
|
8906 |
+
case "D":
|
8907 |
+
output += formatName("D", date.getDay(), dayNamesShort, dayNames);
|
8908 |
+
break;
|
8909 |
+
case "o":
|
8910 |
+
output += formatNumber("o",
|
8911 |
+
Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
|
8912 |
+
break;
|
8913 |
+
case "m":
|
8914 |
+
output += formatNumber("m", date.getMonth() + 1, 2);
|
8915 |
+
break;
|
8916 |
+
case "M":
|
8917 |
+
output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
|
8918 |
+
break;
|
8919 |
+
case "y":
|
8920 |
+
output += (lookAhead("y") ? date.getFullYear() :
|
8921 |
+
(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
|
8922 |
+
break;
|
8923 |
+
case "@":
|
8924 |
+
output += date.getTime();
|
8925 |
+
break;
|
8926 |
+
case "!":
|
8927 |
+
output += date.getTime() * 10000 + this._ticksTo1970;
|
8928 |
+
break;
|
8929 |
+
case "'":
|
8930 |
+
if (lookAhead("'")) {
|
8931 |
+
output += "'";
|
8932 |
+
} else {
|
8933 |
+
literal = true;
|
8934 |
+
}
|
8935 |
+
break;
|
8936 |
+
default:
|
8937 |
+
output += format.charAt(iFormat);
|
8938 |
+
}
|
8939 |
+
}
|
8940 |
+
}
|
8941 |
+
}
|
8942 |
+
return output;
|
8943 |
},
|
8944 |
|
8945 |
+
/* Extract all possible characters from the date format. */
|
8946 |
+
_possibleChars: function (format) {
|
8947 |
+
var iFormat,
|
8948 |
+
chars = "",
|
8949 |
+
literal = false,
|
8950 |
+
// Check whether a format character is doubled
|
8951 |
+
lookAhead = function(match) {
|
8952 |
+
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
|
8953 |
+
if (matches) {
|
8954 |
+
iFormat++;
|
8955 |
+
}
|
8956 |
+
return matches;
|
8957 |
+
};
|
8958 |
|
8959 |
+
for (iFormat = 0; iFormat < format.length; iFormat++) {
|
8960 |
+
if (literal) {
|
8961 |
+
if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
|
8962 |
+
literal = false;
|
8963 |
+
} else {
|
8964 |
+
chars += format.charAt(iFormat);
|
8965 |
+
}
|
8966 |
+
} else {
|
8967 |
+
switch (format.charAt(iFormat)) {
|
8968 |
+
case "d": case "m": case "y": case "@":
|
8969 |
+
chars += "0123456789";
|
8970 |
+
break;
|
8971 |
+
case "D": case "M":
|
8972 |
+
return null; // Accept anything
|
8973 |
+
case "'":
|
8974 |
+
if (lookAhead("'")) {
|
8975 |
+
chars += "'";
|
8976 |
+
} else {
|
8977 |
+
literal = true;
|
8978 |
+
}
|
8979 |
+
break;
|
8980 |
+
default:
|
8981 |
+
chars += format.charAt(iFormat);
|
8982 |
}
|
8983 |
}
|
8984 |
}
|
8985 |
+
return chars;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8986 |
},
|
8987 |
|
8988 |
+
/* Get a setting value, defaulting if necessary. */
|
8989 |
+
_get: function(inst, name) {
|
8990 |
+
return inst.settings[name] !== undefined ?
|
8991 |
+
inst.settings[name] : this._defaults[name];
|
|
|
|
|
|
|
|
|
|
|
8992 |
},
|
8993 |
|
8994 |
+
/* Parse existing date and initialise date picker. */
|
8995 |
+
_setDateFromField: function(inst, noDefault) {
|
8996 |
+
if (inst.input.val() === inst.lastVal) {
|
|
|
|
|
|
|
8997 |
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8998 |
}
|
|
|
8999 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|