Mageho_Sortproducts - Version 1.0.2

Version Notes

Initial Release

Download this release

Release Info

Developer Ilan PARMENTIER
Extension Mageho_Sortproducts
Version 1.0.2
Comparing to
See all releases


Code changes from version 1.0.1 to 1.0.2

Files changed (49) hide show
  1. app/code/local/Mageho/All/Block/System/Config/Form/Fieldset/Extensions.php +0 -80
  2. app/code/local/Mageho/All/Helper/Data.php +0 -9
  3. app/code/local/Mageho/All/etc/adminhtml.xml +0 -30
  4. app/code/local/Mageho/All/etc/config.xml +0 -61
  5. app/code/local/Mageho/All/etc/system.xml +0 -39
  6. app/code/local/Mageho/Sortproducts/Block/Adminhtml/Info.php +0 -63
  7. app/code/local/Mageho/Sortproducts/Block/Adminhtml/Info.php.LCK +0 -1
  8. app/code/local/Mageho/Sortproducts/Block/Adminhtml/Sortgrid.php +0 -112
  9. app/code/local/Mageho/Sortproducts/Block/Adminhtml/Sortgrid.php.LCK +0 -1
  10. app/code/local/Mageho/Sortproducts/Block/Adminhtml/Tab.php +0 -28
  11. app/code/local/Mageho/Sortproducts/Block/Adminhtml/Tab.php.LCK +0 -1
  12. app/code/local/Mageho/Sortproducts/Helper/Data.php +0 -56
  13. app/code/local/Mageho/Sortproducts/Helper/Data.php.LCK +0 -1
  14. app/code/local/Mageho/Sortproducts/Model/Observer.php +0 -36
  15. app/code/local/Mageho/Sortproducts/Model/Observer.php.LCK +0 -1
  16. app/code/local/Mageho/Sortproducts/Model/Resource/Position.php +0 -43
  17. app/code/local/Mageho/Sortproducts/Model/Resource/Position.php.LCK +0 -1
  18. app/code/local/Mageho/Sortproducts/Model/System/Config/Source/Attributes.php +0 -63
  19. app/code/local/Mageho/Sortproducts/Model/System/Config/Source/Attributes.php.LCK +0 -1
  20. app/code/local/Mageho/Sortproducts/controllers/Adminhtml/Mageho/SortproductsController.php +0 -93
  21. app/code/local/Mageho/Sortproducts/controllers/Adminhtml/Mageho/SortproductsController.php.LCK +0 -1
  22. app/code/local/Mageho/Sortproducts/etc/adminhtml.xml +0 -34
  23. app/code/local/Mageho/Sortproducts/etc/adminhtml.xml.LCK +0 -1
  24. app/code/local/Mageho/Sortproducts/etc/config.xml +0 -112
  25. app/code/local/Mageho/Sortproducts/etc/config.xml.LCK +0 -1
  26. app/code/local/Mageho/Sortproducts/etc/system.xml +0 -70
  27. app/code/local/Mageho/Sortproducts/etc/system.xml.LCK +0 -1
  28. app/design/adminhtml/default/default/layout/mageho/sortproducts.xml +0 -73
  29. app/design/adminhtml/default/default/template/mageho/sortproducts/info.phtml +0 -37
  30. app/design/adminhtml/default/default/template/mageho/sortproducts/sortgrid.phtml +0 -83
  31. app/design/adminhtml/default/default/template/mageho/sortproducts/tab.phtml +0 -19
  32. app/etc/modules/Mageho_All.xml +0 -17
  33. app/etc/modules/Mageho_Sortproducts.xml +0 -21
  34. app/locale/fr_FR/Mageho_All.csv +0 -1
  35. app/locale/fr_FR/Mageho_Sortproducts.csv +0 -14
  36. js/mageho/sortproducts/builder.js +0 -136
  37. js/mageho/sortproducts/controls.js +0 -965
  38. js/mageho/sortproducts/dragdrop.js +0 -974
  39. js/mageho/sortproducts/effects.js +0 -1123
  40. js/mageho/sortproducts/excanvas.js +0 -35
  41. js/mageho/sortproducts/loading.gif +0 -0
  42. js/mageho/sortproducts/opentip.css +0 -460
  43. js/mageho/sortproducts/opentip.js +0 -1285
  44. js/mageho/sortproducts/prototype.js +0 -6081
  45. js/mageho/sortproducts/scriptaculous.js +0 -68
  46. js/mageho/sortproducts/slider.js +0 -275
  47. js/mageho/sortproducts/sound.js +0 -59
  48. js/mageho/sortproducts/unittest.js +0 -568
  49. package.xml +4 -4
app/code/local/Mageho/All/Block/System/Config/Form/Fieldset/Extensions.php DELETED
@@ -1,80 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_All
5
- * @copyright Copyright (c) 2012 - 2013 Mageho (http://www.mageho.com)
6
- * @license http://www.mageho.com/license Proprietary License
7
- */
8
-
9
- class Mageho_All_Block_System_Config_Form_Fieldset_Extensions extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
10
- {
11
- protected $_dummyElement;
12
- protected $_fieldRenderer;
13
- protected $_values;
14
-
15
- public function render(Varien_Data_Form_Element_Abstract $element)
16
- {
17
- $html = $this->_getHeaderHtml($element);
18
- $modules = array_keys((array)Mage::getConfig()->getNode('modules')->children());
19
- sort($modules);
20
-
21
- foreach ($modules as $moduleName) {
22
- if (strstr($moduleName,'Mageho_') === false) {
23
- continue;
24
- }
25
- if ($moduleName == 'Mageho_All') {
26
- continue;
27
- }
28
-
29
- $html.= $this->_getFieldHtml($element, $moduleName);
30
- }
31
-
32
- $html .= $this->_getFooterHtml($element);
33
-
34
- return $html;
35
- }
36
-
37
- protected function _getDummyElement()
38
- {
39
- if (empty($this->_dummyElement)) {
40
- $this->_dummyElement = new Varien_Object(array('show_in_default' => 1, 'show_in_website' => 1));
41
- }
42
- return $this->_dummyElement;
43
- }
44
-
45
- protected function _getFieldRenderer()
46
- {
47
- if (empty($this->_fieldRenderer)) {
48
- $this->_fieldRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_field');
49
- }
50
- return $this->_fieldRenderer;
51
- }
52
-
53
- protected function _getFieldHtml($fieldset, $moduleName)
54
- {
55
- $name = strtolower($moduleName);
56
- $version = Mage::getConfig()->getModuleConfig($moduleName)->version;
57
-
58
- $field = $fieldset->addField($name, 'label',
59
- array(
60
- 'name' => $name,
61
- 'label' => $moduleName,
62
- 'value' => $version
63
- ))->setRenderer($this->_getFieldRenderer());
64
-
65
- return $field->toHtml();
66
- }
67
-
68
- protected function _convertVersion($v)
69
- {
70
- $digits = @explode('.', $v);
71
- $version = 0;
72
-
73
- if (is_array($digits)) {
74
- foreach($digits as $k=>$v) {
75
- $version += ($v * pow(10, max(0, (3-$k))));
76
- }
77
- }
78
- return $version;
79
- }
80
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/All/Helper/Data.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_All
5
- * @copyright Copyright (c) 2012 - 2013 Mageho (http://www.mageho.com)
6
- * @license http://www.mageho.com/license Proprietary License
7
- */
8
-
9
- class Mageho_All_Helper_Data extends Mage_Core_Helper_Abstract {}
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/All/etc/adminhtml.xml DELETED
@@ -1,30 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_All
6
- * @copyright Copyright (c) 2012 - 2013 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
- -->
10
- <config>
11
- <acl>
12
- <resources>
13
- <admin>
14
- <children>
15
- <system>
16
- <children>
17
- <config>
18
- <children>
19
- <magehoall>
20
- <title>Mageho</title>
21
- </magehoall>
22
- </children>
23
- </config>
24
- </children>
25
- </system>
26
- </children>
27
- </admin>
28
- </resources>
29
- </acl>
30
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/All/etc/config.xml DELETED
@@ -1,61 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_All
6
- * @copyright Copyright (c) 2012 - 2013 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
- -->
10
- <config>
11
- <modules>
12
- <Mageho_All>
13
- <version>1.0.0</version>
14
- </Mageho_All>
15
- </modules>
16
-
17
- <global>
18
- <blocks>
19
- <magehoall><class>Mageho_All_Block</class></magehoall>
20
- </blocks>
21
-
22
- <models>
23
- <magehoall><class>Mageho_All_Model</class></magehoall>
24
- </models>
25
-
26
- <helpers>
27
- <magehoall><class>Mageho_All_Helper</class></magehoall>
28
- </helpers>
29
- </global>
30
-
31
- <adminhtml>
32
- <acl>
33
- <resources>
34
- <admin>
35
- <children>
36
- <system>
37
- <children>
38
- <config>
39
- <children>
40
- <magehoall>
41
- <title>Mageho</title>
42
- </magehoall>
43
- </children>
44
- </config>
45
- </children>
46
- </system>
47
- </children>
48
- </admin>
49
- </resources>
50
- </acl>
51
- <translate>
52
- <modules>
53
- <Mageho_All>
54
- <files>
55
- <default>Mageho_All.csv</default>
56
- </files>
57
- </Mageho_All>
58
- </modules>
59
- </translate>
60
- </adminhtml>
61
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/All/etc/system.xml DELETED
@@ -1,39 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_All
6
- * @copyright Copyright (c) 2012 - 2013 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
- -->
10
- <config>
11
- <tabs>
12
- <mageho translate="label" module="magehoall">
13
- <label>Mageho</label>
14
- <sort_order>300</sort_order>
15
- </mageho>
16
- </tabs>
17
- <sections>
18
- <magehoall translate="label" module="magehoall">
19
- <label>Info</label>
20
- <tab>mageho</tab>
21
- <frontend_type>text</frontend_type>
22
- <sort_order>0</sort_order>
23
- <show_in_default>1</show_in_default>
24
- <show_in_website>1</show_in_website>
25
- <show_in_store>1</show_in_store>
26
- <groups>
27
- <extensions translate="label">
28
- <label>Installed Mageho Extensions</label>
29
- <frontend_type>text</frontend_type>
30
- <frontend_model>magehoall/system_config_form_fieldset_extensions</frontend_model>
31
- <sort_order>0</sort_order>
32
- <show_in_default>1</show_in_default>
33
- <show_in_website>1</show_in_website>
34
- <show_in_store>1</show_in_store>
35
- </extensions>
36
- </groups>
37
- </magehoall>
38
- </sections>
39
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Block/Adminhtml/Info.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Block_Adminhtml_Info extends Mage_Adminhtml_Block_Template
11
- {
12
- public function __construct()
13
- {
14
- parent::__construct();
15
- $this->setTemplate('mageho/sortproducts/info.phtml');
16
- }
17
-
18
- protected function _prepareLayout()
19
- {
20
- parent::_prepareLayout();
21
- return $this;
22
- }
23
-
24
- public function getSavePercentage($product)
25
- {
26
- if ($product->getPrice() == $product->getFinalPrice()) {
27
- return false;
28
- }
29
-
30
- $save = number_format( (100 - ( $product->getFinalPrice() / $product->getPrice() ) * 100) );
31
- return sprintf('-%d%%', $save);
32
- }
33
-
34
- public function getAttributesToShow()
35
- {
36
- $columnSettings = array();
37
- $attributes = explode(',', Mage::getStoreConfig('mageho_sortproducts/general/show_attributes'));
38
- foreach ($attributes as $attribute) {
39
- $columnSettings[] = trim($attribute);
40
- }
41
-
42
- if (empty($columnSettings)) {
43
- return false;
44
- }
45
-
46
- $countColumnSettings = count($columnSettings);
47
-
48
- if ($countColumnSettings < 1) {
49
- return false;
50
- }
51
-
52
- if ($countColumnSettings == 1 && current($columnSettings) == '') {
53
- return false;
54
- }
55
-
56
- return $columnSettings;
57
- }
58
-
59
- public function getAttributeFrontendLabel($product, $attribute)
60
- {
61
- return $product->getResource()->getAttribute($attribute)->getFrontendLabel();
62
- }
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Block/Adminhtml/Info.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/Block/Adminhtml/Sortgrid.php DELETED
@@ -1,112 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Block_Adminhtml_Sortgrid extends Mage_Adminhtml_Block_Template
11
- {
12
- public function __construct()
13
- {
14
- parent::__construct();
15
- $this->setTemplate('mageho/sortproducts/sortgrid.phtml');
16
- }
17
-
18
- protected function _prepareLayout()
19
- {
20
- parent::_prepareLayout();
21
- return $this;
22
- }
23
-
24
- /**
25
- * ACL validation before html generation
26
- *
27
- * @return string
28
- */
29
- protected function _toHtml()
30
- {
31
- if (Mage::getSingleton('admin/session')->isAllowed('catalog/categories')) {
32
- return parent::_toHtml();
33
- }
34
- return '';
35
- }
36
-
37
- public function getProductsCollection()
38
- {
39
- if (!$this->_productsCollection)
40
- {
41
- $store = (int) $this->getRequest()->getParam('store', 0);
42
- $category_id = (int) $this->getRequest()->getParam('id', 0);
43
-
44
- $category = Mage::getSingleton('catalog/category')->setStoreId($store)->load($category_id);
45
- $products = $category->getProductsPosition();
46
-
47
- $collection = Mage::getModel('catalog/product')->getCollection()
48
- #->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
49
- ->addAttributeToSelect('*')
50
- ->joinField('position', 'catalog/category_product', 'position', 'product_id=entity_id', '{{table}}.category_id='.$category_id, 'left')
51
- #->joinField('qty', 'cataloginventory/stock_item', 'qty', 'product_id=entity_id', '{{table}}.stock_id=1', 'left')
52
- #->joinField('rating', 'review/review_aggregate', 'rating_summary', 'entity_pk_value=entity_id', '{{table}}.store_id=1', 'left') // Modifier store_id
53
- ->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner', $store)
54
- ->addFieldToFilter('visibility', array('in' => array(Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG, Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)))
55
- ->addFieldToFilter('entity_id', array('in' => array_keys($products)))
56
- ->addStoreFilter($store);
57
-
58
- if (Mage::helper('mageho_sortproducts')->displayOnlyEnabledProducts()) {
59
- $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner', $store)
60
- ->addFieldToFilter('status', 1);
61
- }
62
-
63
- // On cache les produits épuisés
64
- if (Mage::helper('mageho_sortproducts')->displayOutStockProducts()) {
65
- if ($websiteId = Mage::app()->getWebsite()->getWebsiteId()) {
66
- $collection->joinField('stock_status', 'cataloginventory/stock_status', 'stock_status', 'product_id=entity_id', array('stock_status' => Mage_CatalogInventory_Model_Stock_Status::STATUS_IN_STOCK, 'website_id' => $websiteId));
67
- }
68
- }
69
-
70
- $collection->setOrder('position', 'asc');
71
-
72
- if ($limit = Mage::helper('mageho_sortproducts')->limitSortProducts()) {
73
- $collection->setPageSize($limit);
74
- }
75
-
76
- $collection->setCurPage(1);
77
-
78
- $this->_productsCollection = $collection;
79
- }
80
- return $this->_productsCollection;
81
- }
82
-
83
- public function getImageWidth()
84
- {
85
- return Mage::helper('mageho_sortproducts')->getImageWidth();
86
- }
87
-
88
- /**
89
- * Retrieve Session Form Key
90
- *
91
- * @return string
92
- */
93
- public function getFormKey()
94
- {
95
- return Mage::getSingleton('core/session')->getFormKey();
96
- }
97
-
98
- public function getSaveUrl()
99
- {
100
- return $this->getUrl('*/*/save', array('_current' => true));
101
- }
102
-
103
- public function getProductInfoUrl($product)
104
- {
105
- return $this->getUrl('*/*/info', array('id' => $product->getId(), '_current' => true));
106
- }
107
-
108
- public function isDisabled($product)
109
- {
110
- return $product->getStatus() && ($product->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
111
- }
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Block/Adminhtml/Sortgrid.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/Block/Adminhtml/Tab.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Block_Adminhtml_Tab extends Mage_Adminhtml_Block_Template
11
- {
12
- public function __construct()
13
- {
14
- parent::__construct();
15
- $this->setTemplate('mageho/sortproducts/tab.phtml');
16
- }
17
-
18
- protected function _prepareLayout()
19
- {
20
- parent::_prepareLayout();
21
- return $this;
22
- }
23
-
24
- public function getSortProductsUrl()
25
- {
26
- return $this->getUrl('adminhtml/mageho_sortproducts/index', array('_current' => true));
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Block/Adminhtml/Tab.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/Helper/Data.php DELETED
@@ -1,56 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Helper_Data extends Mage_Core_Helper_Abstract
11
- {
12
- const SORTPRODUCTS_DISPLAY_OUT_STOCK_PRODUCTS = 'sortproducts/general/display_out_stock_products';
13
- const SORTPRODUCTS_DISPLAY_ONLY_ENABLED_PRODUCTS = 'sortproducts/general/display_only_enabled_products';
14
- const SORTPRODUCTS_LIMIT_PRODUCTS = 'sortproducts/general/limit_products';
15
-
16
- /**
17
- * Translate
18
- *
19
- * @return string
20
- */
21
- public function __()
22
- {
23
- $args = func_get_args();
24
- $expr = new Mage_Core_Model_Translate_Expr(array_shift($args), 'Mageho_Sortproducts');
25
- array_unshift($args, $expr);
26
- return utf8_encode(Mage::app()->getTranslator()->translate($args));
27
- }
28
-
29
- public function displayOutStockProducts()
30
- {
31
- return Mage::getStoreConfigFlag(self::SORTPRODUCTS_DISPLAY_OUT_STOCK_PRODUCTS);
32
- }
33
-
34
- public function displayOnlyEnabledProducts()
35
- {
36
- return Mage::getStoreConfigFlag(self::SORTPRODUCTS_DISPLAY_ONLY_ENABLED_PRODUCTS);
37
- }
38
-
39
- public function limitSortProducts()
40
- {
41
- $limit = (int) Mage::getStoreConfig(self::SORTPRODUCTS_LIMIT_PRODUCTS, 0);
42
- if ($limit > 0) {
43
- return $limit;
44
- }
45
- }
46
-
47
- public function getImageWidth()
48
- {
49
- $width = (int) Mage::getStoreConfig('mageho_sortproducts/general/image_width');
50
- if ($width > 0) {
51
- return $width;
52
- } else {
53
- return 60;
54
- }
55
- }
56
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Helper/Data.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/Model/Observer.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Model_Observer
11
- {
12
- public function addTabToCategoryPage($observer)
13
- {
14
- $event = $observer->getEvent();
15
- $tabs = $event->getTabs();
16
- $category = $tabs->getCategory();
17
- $count = $category->getProductCount();
18
-
19
- if ($category->getId() && ($count > 1))
20
- {
21
- $tabs->addTab('mageho_sortproducts', array(
22
- 'label' => Mage::helper('mageho_sortproducts')->__('Sort Category Products'),
23
- 'content' => $tabs->getLayout()->createBlock('mageho_sortproducts/adminhtml_tab')->setTemplate('mageho/sortproducts/tab.phtml')->toHtml()
24
-
25
- /*
26
- * Pour charger le bloc en ajax ajouter ces lignes et enlever la clé content juste au-dessus
27
- */
28
-
29
- #'url' => Mage::getUrl('adminhtml/mageho_sortproducts/tab', array('_current' => true)),
30
- #'class' => 'ajax'
31
- ));
32
- }
33
-
34
- return $this;
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Model/Observer.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/Model/Resource/Position.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproduct
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- #class Mageho_Sortproducts_Model_Mysql4_Position extends Mage_Catalog_Model_Resource_Eav_Mysql4_Category
11
- class Mageho_Sortproducts_Model_Resource_Position extends Mage_Catalog_Model_Resource_Category
12
- {
13
- /**
14
- * Initialize resource
15
- */
16
- public function __construct()
17
- {
18
- parent::__construct();
19
- $resource = Mage::getSingleton('core/resource');
20
- $this->setType('catalog_category')
21
- ->setConnection(
22
- $resource->getConnection('catalog_read'),
23
- $resource->getConnection('catalog_write')
24
- );
25
-
26
- $this->_productCategoryTable = $resource->getTableName('catalog/category_product');
27
- $this->_productCategoryIndexTable = $resource->getTableName('catalog/category_product_index');
28
- }
29
-
30
- public function save($position, $productId, $categoryId)
31
- {
32
- $condition = array(
33
- $this->_getWriteAdapter()->quoteInto("product_id=?", $productId),
34
- $this->_getWriteAdapter()->quoteInto("category_id=?", $categoryId)
35
- );
36
-
37
- $db = $this->_getWriteAdapter();
38
- $db->update($this->_productCategoryTable, array('position' => $position), $condition);
39
- $db->update($this->_productCategoryIndexTable, array('position' => $position), $condition);
40
-
41
- return $this;
42
- }
43
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Model/Resource/Position.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/Model/System/Config/Source/Attributes.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Model_System_Config_Source_Attributes
11
- {
12
- public $doNotDisplayAttributesArray = array('price', 'tier_price', 'group_price', 'special_price', 'name', 'sku',
13
- 'description', 'tax_class_id', 'url_key', 'options_container', 'price_view', 'gift_message_available',
14
- 'custom_design', 'custom_design_from', 'custom_design_to', 'custom_layout_update', 'page_layout',
15
- 'visibility', 'status', 'enable_googlecheckout');
16
-
17
- public function toOptionArray()
18
- {
19
- $cols = array();
20
- $cols[] = array('value' => '', 'label' => Mage::helper('mageho_sortproducts')->__('None'));
21
- $cols[] = array('value' => 'type_id', 'label' => Mage::helper('mageho_sortproducts')->__('Product Type (simple, bundle, etc)'));
22
- $cols[] = array('value' => 'attribute_set_id', 'label' => Mage::helper('mageho_sortproducts')->__('Attribute Set'));
23
- $cols[] = array('value' => 'created_at', 'label' => Mage::helper('mageho_sortproducts')->__('Date Created'));
24
-
25
- foreach ($this->getAttributes() as $attribute) {
26
- $label = $attribute->getFrontendLabel() . ' - ' . $attribute->getAttributeCode() . ' #'.$attribute->getAttributeId();
27
-
28
- $cols[] = array('value' => $attribute->getAttributeCode(), 'label' => $label);
29
- }
30
-
31
- return $cols;
32
- }
33
-
34
- /**
35
- * @return Mage_Eav_Model_Mysql4_Entity_Attribute_Collection
36
- */
37
- protected function getAttributes()
38
- {
39
- if (version_compare(Mage::getVersion(), '1.4', '>=')) {
40
- $collection = Mage::getResourceModel( 'catalog/product_attribute_collection');
41
- } else {
42
- $type_id = Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId();
43
- $collection = Mage::getResourceModel('eav/entity_attribute_collection');
44
- $collection->setEntityTypeFilter($type_id);
45
- }
46
-
47
- $collection->addFilter('is_visible', 1);
48
-
49
- $allowedAttributes = array();
50
- foreach ($collection->getItems() as $attribute) {
51
- if ( in_array($attribute->getFrontendInput(), array('media_image', 'gallery')) ) {
52
- continue;
53
- }
54
- if ( in_array($attribute->getAttributeCode(), $this->doNotDisplayAttributesArray) ) {
55
- continue;
56
- }
57
-
58
- $allowedAttributes[] = $attribute;
59
- }
60
-
61
- return $allowedAttributes;
62
- }
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/Model/System/Config/Source/Attributes.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/controllers/Adminhtml/Mageho/SortproductsController.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @version 1.0.0
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
-
10
- class Mageho_Sortproducts_Adminhtml_Mageho_SortproductsController
11
- extends Mage_Adminhtml_Controller_Action
12
- {
13
- public function indexAction()
14
- {
15
- $this->loadLayout();
16
- $this->renderLayout();
17
- }
18
-
19
- public function tabAction()
20
- {
21
- $this->getResponse()->setBody(
22
- $this->getLayout()->createBlock('mageho_sortproducts/adminhtml_tab')->toHtml()
23
- );
24
- }
25
-
26
- public function infoAction()
27
- {
28
- $productId = $this->getRequest()->getParam('id', false);
29
- $product = Mage::getModel('catalog/product')
30
- ->setStoreId($this->getRequest()->getParam('store', 0));
31
-
32
- if ($productId) {
33
- $product->load($productId);
34
-
35
- Mage::register('product', $product);
36
- Mage::register('current_product', $product);
37
-
38
- $this->getResponse()->setBody(
39
- $this->getLayout()->createBlock('mageho_sortproducts/adminhtml_info')->toHtml()
40
- );
41
- }
42
- }
43
-
44
- public function saveAction()
45
- {
46
- $data = $this->getRequest()->getPost('data');
47
- $categoryId = $this->getRequest()->getParam('id', false);
48
-
49
- try {
50
- if (! $data) {
51
- throw new Exception('no data post parameters');
52
- }
53
-
54
- $category = Mage::getModel('catalog/category')
55
- ->setStoreId($this->getRequest()->getParam('store', 0));
56
-
57
- if ($categoryId) {
58
- $category->load($categoryId);
59
-
60
- if ($category->getId()) {
61
- parse_str($data);
62
- for ($i = 0; $i < count($sortlist); $i++) {
63
- $position = $i;
64
- $productId = $sortlist[$i];
65
-
66
- Mage::getResourceModel('mageho_sortproducts/position')->save($position, $productId, $category->getId());
67
- }
68
-
69
- Mage::app()->cleanCache(array(Mage_Catalog_Model_Category::CACHE_TAG.'_'.$category->getId()));
70
-
71
- Mage::getSingleton('adminhtml/session')->addSuccess(
72
- Mage::helper('mageho_sortproducts')->__('The position of products has been saved with success.')
73
- );
74
- }
75
- }
76
- } catch (Exception $e) {
77
- Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
78
- }
79
-
80
- $resetUrl = Mage::helper('adminhtml')->getUrl('adminhtml/catalog_category/edit', array('active_tab_id' => 'category_info_tabs_sortproducts', '_current' => true));
81
- $this->getResponse()->setBody("window.top.categoryReset('{$resetUrl}', true);");
82
- }
83
-
84
- /**
85
- * Check if admin has permissions to visit categories pages
86
- *
87
- * @return boolean
88
- */
89
- protected function _isAllowed()
90
- {
91
- return Mage::getSingleton('admin/session')->isAllowed('catalog/categories');
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/controllers/Adminhtml/Mageho/SortproductsController.php.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/etc/adminhtml.xml DELETED
@@ -1,34 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_SortProducts
6
- * @version 1.0.0
7
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
8
- * @license http://www.mageho.com/license Proprietary License
9
- */
10
- -->
11
- <config>
12
- <acl>
13
- <resources>
14
- <all translate="title" module="mageho_sortproducts">
15
- <title>Allow Everything</title>
16
- </all>
17
- <admin>
18
- <children>
19
- <system>
20
- <children>
21
- <config>
22
- <children>
23
- <mageho_sortproducts translate="title" module="mageho_sortproducts">
24
- <title>Merchandising</title>
25
- </mageho_sortproducts>
26
- </children>
27
- </config>
28
- </children>
29
- </system>
30
- </children>
31
- </admin>
32
- </resources>
33
- </acl>
34
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/etc/adminhtml.xml.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/etc/config.xml DELETED
@@ -1,112 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_Sortproducts
6
- * @version 1.0.0
7
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
8
- * @license http://www.mageho.com/license Proprietary License
9
- */
10
- -->
11
- <config>
12
- <modules>
13
- <Mageho_Sortproducts>
14
- <version>1.0.0</version>
15
- </Mageho_Sortproducts>
16
- </modules>
17
- <global>
18
- <blocks>
19
- <mageho_sortproducts>
20
- <class>Mageho_Sortproducts_Block</class>
21
- </mageho_sortproducts>
22
- </blocks>
23
- <helpers>
24
- <mageho_sortproducts>
25
- <class>Mageho_Sortproducts_Helper</class>
26
- </mageho_sortproducts>
27
- </helpers>
28
- <models>
29
- <mageho_sortproducts>
30
- <class>Mageho_Sortproducts_Model</class>
31
- <!-- resourceModel>sortproducts_mysql4</resourceModel -->
32
- <resourceModel>mageho_sortproducts_resource</resourceModel>
33
- </mageho_sortproducts>
34
- <!--sortproducts_mysql4>
35
- <class>Mageho_Sortproducts_Model_Mysql4</class>
36
- </sortproducts_mysql4-->
37
- <mageho_sortproducts_resource>
38
- <class>Mageho_Sortproducts_Model_Resource</class>
39
- </mageho_sortproducts_resource>
40
- </models>
41
- <resources>
42
- <mageho_sortproducts_setup>
43
- <setup>
44
- <module>Mageho_Sortproducts</module>
45
- </setup>
46
- <connection>
47
- <use>core_setup</use>
48
- </connection>
49
- </mageho_sortproducts_setup>
50
- <mageho_sortproducts_write>
51
- <connection>
52
- <use>core_write</use>
53
- </connection>
54
- </mageho_sortproducts_write>
55
- <mageho_sortproducts_read>
56
- <connection>
57
- <use>core_read</use>
58
- </connection>
59
- </mageho_sortproducts_read>
60
- </resources>
61
- <events>
62
- <adminhtml_catalog_category_tabs>
63
- <observers>
64
- <mageho_sortproducts>
65
- <type>singleton</type>
66
- <class>mageho_sortproducts/observer</class>
67
- <method>addTabToCategoryPage</method>
68
- </mageho_sortproducts>
69
- </observers>
70
- </adminhtml_catalog_category_tabs>
71
- </events>
72
- </global>
73
- <admin>
74
- <routers>
75
- <adminhtml>
76
- <args>
77
- <modules>
78
- <Mageho_Sortproducts before="Mage_Adminhtml">Mageho_Sortproducts_Adminhtml</Mageho_Sortproducts>
79
- </modules>
80
- </args>
81
- </adminhtml>
82
- </routers>
83
- </admin>
84
- <adminhtml>
85
- <translate>
86
- <modules>
87
- <Mageho_Sortproducts>
88
- <files>
89
- <default>Mageho_Sortproducts.csv</default>
90
- </files>
91
- </Mageho_Sortproducts>
92
- </modules>
93
- </translate>
94
- <layout>
95
- <updates>
96
- <mageho_sortproducts>
97
- <file>mageho/sortproducts.xml</file>
98
- </mageho_sortproducts>
99
- </updates>
100
- </layout>
101
- </adminhtml>
102
- <default>
103
- <mageho_sortproducts>
104
- <general>
105
- <limit_products>0</limit_products>
106
- <image_width>50</image_width>
107
- <display_only_enabled_products>0</display_only_enabled_products>
108
- <display_out_stock_products>0</display_out_stock_products>
109
- </general>
110
- </mageho_sortproducts>
111
- </default>
112
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/etc/config.xml.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/code/local/Mageho/Sortproducts/etc/system.xml DELETED
@@ -1,70 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_Sortproducts
6
- * @version 1.0.0
7
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
8
- * @license http://www.mageho.com/license Proprietary License
9
- */
10
- -->
11
- <config>
12
- <sections>
13
- <mageho_sortproducts translate="label" module="mageho_sortproducts">
14
- <label>Merchandising</label>
15
- <tab>mageho</tab>
16
- <frontend_type>text</frontend_type>
17
- <sort_order>200</sort_order>
18
- <show_in_default>1</show_in_default>
19
- <show_in_website>1</show_in_website>
20
- <show_in_store>0</show_in_store>
21
- <groups>
22
- <general translate="label">
23
- <label>General</label>
24
- <show_in_default>1</show_in_default>
25
- <show_in_website>0</show_in_website>
26
- <show_in_store>0</show_in_store>
27
- <fields>
28
- <limit_products translate="label comment">
29
- <label>Limit number of products in iframe</label>
30
- <comment>Enter 0 for no limit - This parameter can improve performance loading</comment>
31
- <frontend_type>text</frontend_type>
32
- <sort_order>0</sort_order>
33
- <show_in_default>1</show_in_default>
34
- <show_in_website>1</show_in_website>
35
- </limit_products>
36
- <image_width translate="label">
37
- <label>Image Width</label>
38
- <frontend_type>text</frontend_type>
39
- <sort_order>10</sort_order>
40
- <show_in_default>1</show_in_default>
41
- <show_in_website>1</show_in_website>
42
- </image_width>
43
- <show_attributes translate="label">
44
- <label>Show Attributes</label>
45
- <frontend_type>multiselect</frontend_type>
46
- <source_model>Mageho_Sortproducts_Model_System_Config_Source_Attributes</source_model>
47
- <sort_order>20</sort_order>
48
- <show_in_default>1</show_in_default>
49
- <show_in_website>1</show_in_website>
50
- </show_attributes>
51
- <display_only_enabled_products translate="label">
52
- <label>Display Only Enabled Products</label>
53
- <frontend_type>select</frontend_type>
54
- <sort_order>30</sort_order>
55
- <show_in_default>1</show_in_default>
56
- <source_model>adminhtml/system_config_source_yesno</source_model>
57
- </display_only_enabled_products>
58
- <display_out_stock_products translate="label">
59
- <label>Display Out of Stock Products</label>
60
- <frontend_type>select</frontend_type>
61
- <sort_order>40</sort_order>
62
- <show_in_default>1</show_in_default>
63
- <source_model>adminhtml/system_config_source_yesno</source_model>
64
- </display_out_stock_products>
65
- </fields>
66
- </general>
67
- </groups>
68
- </mageho_sortproducts>
69
- </sections>
70
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Mageho/Sortproducts/etc/system.xml.LCK DELETED
@@ -1 +0,0 @@
1
- Ilan Parmentier||ilan.parmentier@artbambou.com
 
app/design/adminhtml/default/default/layout/mageho/sortproducts.xml DELETED
@@ -1,73 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_Sortproducts
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- * @version 1.0.0
9
- */
10
- -->
11
- <layout version="0.1.0">
12
- <adminhtml_mageho_sortproducts_index>
13
- <update handle="popup" />
14
- <remove name="head.calendar" />
15
- <remove name="notifications" />
16
- <remove name="footer" />
17
-
18
- <reference name="head">
19
- <action method="removeItem"><type>js</type><name>prototype/prototype.js</name></action>
20
- <action method="removeItem"><type>js</type><name>prototype/window.js</name></action>
21
- <action method="removeItem"><type>js</type><name>scriptaculous/builder.js</name></action>
22
- <action method="removeItem"><type>js</type><name>scriptaculous/effects.js</name></action>
23
- <action method="removeItem"><type>js</type><name>scriptaculous/dragdrop.js</name></action>
24
- <action method="removeItem"><type>js</type><name>scriptaculous/controls.js</name></action>
25
- <action method="removeItem"><type>js</type><name>scriptaculous/slider.js</name></action>
26
- <action method="removeItem"><type>js</type><name>lib/ccard.js</name></action>
27
- <action method="removeItem"><type>js</type><name>prototype/validation.js</name></action>
28
- <action method="removeItem"><type>js</type><name>varien/js.js</name></action>
29
- <action method="removeItem"><type>js</type><name>mage/translate.js</name></action>
30
- <action method="removeItem"><type>js</type><name>mage/adminhtml/hash.js</name></action>
31
- <action method="removeItem"><type>js</type><name>mage/adminhtml/events.js</name></action>
32
- <action method="removeItem"><type>js</type><name>mage/adminhtml/loader.js</name></action>
33
- <action method="removeItem"><type>js</type><name>mage/adminhtml/grid.js</name></action>
34
- <action method="removeItem"><type>js</type><name>mage/adminhtml/tabs.js</name></action>
35
- <action method="removeItem"><type>js</type><name>mage/adminhtml/form.js</name></action>
36
- <action method="removeItem"><type>js</type><name>mage/adminhtml/accordion.js</name></action>
37
- <action method="removeItem"><type>js</type><name>mage/adminhtml/tools.js</name></action>
38
- <action method="removeItem"><type>js</type><name>mage/adminhtml/uploader.js</name></action>
39
- <action method="removeItem"><type>js</type><name>mage/adminhtml/product.js</name></action>
40
- <action method="removeItem"><type>js</type><name>calendar/calendar.js</name></action>
41
- <action method="removeItem"><type>js</type><name>calendar/calendar-setup.js</name></action>
42
- <action method="removeItem"><type>js</type><name>mage/adminhtml/rules.js</name></action>
43
-
44
- <!-- Extension EmProductsFilter -->
45
- <action method="removeItem"><type>js</type><name>em/productsfilter/productsfilter.js</name></action>
46
-
47
- <!-- Extension Files Download -->
48
- <action method="removeItem"><type>js</type><name>mageworx/fileuploader.js</name></action>
49
-
50
- <!-- Extension EnhancedGrid -->
51
- <action method="removeItem"><type>js</type><name>tbt/enhancedgrid/enhancedgrid.js</name></action>
52
- <action method="removeItem"><type>js</type><name>tbt/enhancedgrid/egsupplemental.js</name></action>
53
- <action method="removeItem"><type>js</type><name>tbt/enhancedgrid/customfunctions/catalog_products.js</name></action>
54
-
55
- <action method="addJs"><script>mageho/sortproducts/prototype.js</script></action>
56
-
57
- <!-- Ne fonctionne que si les fichiers javascript ne sont pas fusionnés -->
58
- <!-- action method="addJs"><script>mageho/sortproducts/scriptaculous.js</script></action -->
59
-
60
- <action method="addJs"><script>mageho/sortproducts/effects.js</script></action>
61
- <action method="addJs"><script>mageho/sortproducts/dragdrop.js</script></action>
62
- <action method="addJs"><script>mageho/sortproducts/opentip.js</script></action>
63
- <action method="addJs"><script>mageho/sortproducts/excanvas.js</script></action>
64
- <action method="addItem"><type>js_css</type><name>mageho/sortproducts/opentip.css</name></action>
65
-
66
- <action method="addCss"><name>mageho/sortproducts/sortproducts.css</name></action>
67
- </reference>
68
-
69
- <reference name="content">
70
- <block type="mageho_sortproducts/adminhtml_sortgrid" name="mageho.sortgrid" />
71
- </reference>
72
- </adminhtml_mageho_sortproducts_index>
73
- </layout>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/mageho/sortproducts/info.phtml DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
6
- * @license http://www.mageho.com/license Proprietary License
7
- * @version 1.0.0
8
- */
9
- ?>
10
- <?php $_product = Mage::registry('current_product'); ?>
11
- <div>
12
- <ul class="square-list">
13
- <li><small><?php echo $this->__('ID'); ?> : <?php echo $_product->getId(); ?></small></li>
14
-
15
- <?php if ($_product->getSku()): ?>
16
- <li><small><?php echo $this->__('SKU'); ?> : <?php echo $_product->getSku(); ?></small></li>
17
- <?php endif; ?>
18
-
19
- <li>
20
- <?php echo $this->__('Price'); ?> :
21
- <?php if ($_product->getSpecialPrice()): ?>
22
- <del><?php echo $this->helper('core')->currency($_product->getPrice()); ?></del>
23
- <ins><?php echo $this->helper('core')->currency($_product->getSpecialPrice()); ?></ins>
24
-
25
- <?php echo $this->getSavePercentage($_product); ?>
26
- <?php else: ?>
27
- <?php echo $this->helper('core')->currency($_product->getPrice()); ?>
28
- <?php endif; ?>
29
- </li>
30
-
31
- <?php if ($attributes = $this->getAttributesToShow()): ?>
32
- <?php foreach($attributes as $attribute): ?>
33
- <li><?php echo $this->getAttributeFrontendLabel($_product, $attribute); ?> : <?php echo ($_product->getData($attribute) ? $_product->getData($attribute) : $this->__('N.C.')); ?></li>
34
- <?php endforeach; ?>
35
- <?php endif; ?>
36
- </ul>
37
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/mageho/sortproducts/sortgrid.phtml DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
6
- * @license http://www.mageho.com/license Proprietary License
7
- * @version 1.0.0
8
- */
9
- ?>
10
- <?php if (($_products = $this->getProductsCollection()) && $_products->getSize()): ?>
11
- <script type="text/javascript">
12
- //<![CDATA[
13
- document.observe('dom:loaded', function() {
14
- Sortable.create('sortlist', {
15
- tag: 'li',
16
- only: 'sorting',
17
- hoverclass: 'over',
18
- overlap: 'horizontal',
19
- ghosting: false,
20
- constraint: false,
21
- scroll: window,
22
- scrollSensitivity: 30,
23
- scrollSpeed: 25
24
- })
25
-
26
- $$('button.button-save-sortable').each(function(el) {
27
- el.onclick = function() {
28
- new Ajax.Request("<?php echo $this->getSaveUrl(); ?>", {
29
- method: "post",
30
- evalScripts: true,
31
- onLoading: function() { parent.$('loading-mask').show() },
32
- onSuccess: function(transport) { parent.$('loading-mask').hide() },
33
- onComplete:function(transport) { eval(transport.responseText) },
34
- parameters: {
35
- data: Sortable.serialize('sortlist'),
36
- form_key: '<?php echo $this->getFormKey(); ?>'
37
- }
38
- })
39
- }
40
- })
41
- })
42
- //]]>
43
- </script>
44
-
45
- <div id="messages"></div>
46
-
47
- <div class="content-header">
48
- <div class="content-buttons-placeholder"><p class="content-buttons form-buttons"><button type="button" class="scalable button-save-sortable"><span><?php echo $this->__('Save Products Position'); ?></span></button></p></div>
49
- </div>
50
-
51
- <div id="sortlist-wrapper">
52
- <ul id="sortlist">
53
- <?php foreach ($_products->getItems() as $_product): ?>
54
- <li id="product_<?php echo $_product->getId(); ?>" class="sorting">
55
- <div class="product_container">
56
-
57
- <?php
58
- # Error message for no products with image
59
- # core/Mage/Catalog/Helper/Image.php(163): Mage_Catalog_Model_Product_Image->setBaseFile('no_selection')
60
-
61
- try {
62
- $imageUrl = $this->helper('catalog/image')->init($_product, 'thumbnail')->resize($this->getImageWidth());
63
- } catch(Exception $e) {
64
- $imageUrl = Mage::getDesign()->getSkinUrl('mageho/sortproducts/placeholder.jpg');
65
- }
66
- ?>
67
-
68
- <img src="<?php echo $imageUrl; ?>" width="<?php echo $this->getImageWidth(); ?>" alt="<?php echo $this->htmlEscape($_product->getName()); ?>" class="sorting-image" longdesc="<?php echo $this->getProductInfoUrl($_product); ?>" <?php if ($this->isDisabled($_product)): ?>style="opacity:0.3"<?php endif; ?> />
69
- <?php if (!$_product->isSaleable() && !$_product->isConfigurable()): ?><div class="saleable"><?php echo $this->helper('catalog')->__('Out of stock'); ?></div><?php endif; ?>
70
- </div>
71
- </li>
72
- <?php endforeach; ?>
73
- </ul>
74
- </div>
75
-
76
- <script type="text/javascript">
77
- //<![CDATA[
78
- $$('.sorting-image').each(function(image) {
79
- image.addTip({ title: image.alt, style: 'slick', ajax: { url: image.readAttribute('longdesc'), options: { parameters: { form_key: '<?php echo $this->getFormKey(); ?>'} } } });
80
- });
81
- //]]>
82
- </script>
83
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/mageho/sortproducts/tab.phtml DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- /*
3
- * @category Mageho
4
- * @package Mageho_Sortproducts
5
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
6
- * @license http://www.mageho.com/license Proprietary License
7
- * @version 1.0.0
8
- */
9
- ?>
10
- <div class="entry-edit">
11
- <div class="entry-edit-head">
12
- <h4 class="icon-head head-edit-form fieldset-legend"><?php echo $this->__('Sort Products'); ?></h4>
13
- <div class="form-buttons"></div>
14
- </div>
15
-
16
- <div class="fieldset">
17
- <iframe id="sortproductsdraganddrop" src="<?php echo $this->getSortProductsUrl(); ?>" width="100%" height="500" scrolling="yes" allowtransparency="true" frameborder="0" style="overflow:auto;"></iframe>
18
- </div>
19
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/etc/modules/Mageho_All.xml DELETED
@@ -1,17 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_All
6
- * @copyright Copyright (c) 2012 - 2013 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
- -->
10
- <config>
11
- <modules>
12
- <Mageho_All>
13
- <active>true</active>
14
- <codePool>local</codePool>
15
- </Mageho_All>
16
- </modules>
17
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/etc/modules/Mageho_Sortproducts.xml DELETED
@@ -1,21 +0,0 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /*
4
- * @category Mageho
5
- * @package Mageho_Sortproducts
6
- * @copyright Copyright (c) 2012 Mageho (http://www.mageho.com)
7
- * @license http://www.mageho.com/license Proprietary License
8
- */
9
- -->
10
- <config>
11
- <modules>
12
- <Mageho_Sortproducts>
13
- <active>true</active>
14
- <codePool>local</codePool>
15
- <depends>
16
- <Mage_Adminhtml />
17
- <Mage_Catalog />
18
- </depends>
19
- </Mageho_Sortproducts>
20
- </modules>
21
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/fr_FR/Mageho_All.csv DELETED
@@ -1 +0,0 @@
1
- "Installed Mageho Extensions","Extensions Mageho installées"
 
app/locale/fr_FR/Mageho_Sortproducts.csv DELETED
@@ -1,14 +0,0 @@
1
- "%d position's product have been saved.","%s positions de produit ont �t� sauvegard�es."
2
- "Enter 0 for no limit - This parameter can improve performance loading","Entrer 0 pour aucune limitation - Ce param�tre peut am�liorer les performances de chargement."
3
- "Display Only Enabled Products","Afficher seulement les produits dont le statut est activ�"
4
- "Display Out of Stock Products","Afficher les produits en rupture de stock"
5
- "Image Width","Taille d'image"
6
- "Limit number of products in iframe","Limiter le nombre de produits"
7
- "General","G�n�ral"
8
- "None","Aucun"
9
- "Product Type (simple, bundle, etc)","Type produit (simple, bundle, etc)"
10
- "Save Products Position","Sauvegarder la position des produits"
11
- "Show Attributes","Afficher les attributs produits suivants"
12
- "Sort Products","Trier les produits"
13
- "Sort Category Products","Merchandising produits"
14
- "The position of products has been saved with success.","La position des produits a bien �t� sauvegard�e avec succ�s."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/builder.js DELETED
@@ -1,136 +0,0 @@
1
- // script.aculo.us builder.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- //
5
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
6
- // For details, see the script.aculo.us web site: http://script.aculo.us/
7
-
8
- var Builder = {
9
- NODEMAP: {
10
- AREA: 'map',
11
- CAPTION: 'table',
12
- COL: 'table',
13
- COLGROUP: 'table',
14
- LEGEND: 'fieldset',
15
- OPTGROUP: 'select',
16
- OPTION: 'select',
17
- PARAM: 'object',
18
- TBODY: 'table',
19
- TD: 'table',
20
- TFOOT: 'table',
21
- TH: 'table',
22
- THEAD: 'table',
23
- TR: 'table'
24
- },
25
- // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
26
- // due to a Firefox bug
27
- node: function(elementName) {
28
- elementName = elementName.toUpperCase();
29
-
30
- // try innerHTML approach
31
- var parentTag = this.NODEMAP[elementName] || 'div';
32
- var parentElement = document.createElement(parentTag);
33
- try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
34
- parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
35
- } catch(e) {}
36
- var element = parentElement.firstChild || null;
37
-
38
- // see if browser added wrapping tags
39
- if(element && (element.tagName.toUpperCase() != elementName))
40
- element = element.getElementsByTagName(elementName)[0];
41
-
42
- // fallback to createElement approach
43
- if(!element) element = document.createElement(elementName);
44
-
45
- // abort if nothing could be created
46
- if(!element) return;
47
-
48
- // attributes (or text)
49
- if(arguments[1])
50
- if(this._isStringOrNumber(arguments[1]) ||
51
- (arguments[1] instanceof Array) ||
52
- arguments[1].tagName) {
53
- this._children(element, arguments[1]);
54
- } else {
55
- var attrs = this._attributes(arguments[1]);
56
- if(attrs.length) {
57
- try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
58
- parentElement.innerHTML = "<" +elementName + " " +
59
- attrs + "></" + elementName + ">";
60
- } catch(e) {}
61
- element = parentElement.firstChild || null;
62
- // workaround firefox 1.0.X bug
63
- if(!element) {
64
- element = document.createElement(elementName);
65
- for(attr in arguments[1])
66
- element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
67
- }
68
- if(element.tagName.toUpperCase() != elementName)
69
- element = parentElement.getElementsByTagName(elementName)[0];
70
- }
71
- }
72
-
73
- // text, or array of children
74
- if(arguments[2])
75
- this._children(element, arguments[2]);
76
-
77
- return $(element);
78
- },
79
- _text: function(text) {
80
- return document.createTextNode(text);
81
- },
82
-
83
- ATTR_MAP: {
84
- 'className': 'class',
85
- 'htmlFor': 'for'
86
- },
87
-
88
- _attributes: function(attributes) {
89
- var attrs = [];
90
- for(attribute in attributes)
91
- attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
92
- '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'&quot;') + '"');
93
- return attrs.join(" ");
94
- },
95
- _children: function(element, children) {
96
- if(children.tagName) {
97
- element.appendChild(children);
98
- return;
99
- }
100
- if(typeof children=='object') { // array can hold nodes and text
101
- children.flatten().each( function(e) {
102
- if(typeof e=='object')
103
- element.appendChild(e);
104
- else
105
- if(Builder._isStringOrNumber(e))
106
- element.appendChild(Builder._text(e));
107
- });
108
- } else
109
- if(Builder._isStringOrNumber(children))
110
- element.appendChild(Builder._text(children));
111
- },
112
- _isStringOrNumber: function(param) {
113
- return(typeof param=='string' || typeof param=='number');
114
- },
115
- build: function(html) {
116
- var element = this.node('div');
117
- $(element).update(html.strip());
118
- return element.down();
119
- },
120
- dump: function(scope) {
121
- if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
122
-
123
- var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
124
- "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
125
- "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
126
- "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
127
- "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
128
- "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
129
-
130
- tags.each( function(tag){
131
- scope[tag] = function() {
132
- return Builder.node.apply(Builder, [tag].concat($A(arguments)));
133
- };
134
- });
135
- }
136
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/controls.js DELETED
@@ -1,965 +0,0 @@
1
- // script.aculo.us controls.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- // (c) 2005-2010 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
5
- // (c) 2005-2010 Jon Tirsen (http://www.tirsen.com)
6
- // Contributors:
7
- // Richard Livsey
8
- // Rahul Bhargava
9
- // Rob Wills
10
- //
11
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
12
- // For details, see the script.aculo.us web site: http://script.aculo.us/
13
-
14
- // Autocompleter.Base handles all the autocompletion functionality
15
- // that's independent of the data source for autocompletion. This
16
- // includes drawing the autocompletion menu, observing keyboard
17
- // and mouse events, and similar.
18
- //
19
- // Specific autocompleters need to provide, at the very least,
20
- // a getUpdatedChoices function that will be invoked every time
21
- // the text inside the monitored textbox changes. This method
22
- // should get the text for which to provide autocompletion by
23
- // invoking this.getToken(), NOT by directly accessing
24
- // this.element.value. This is to allow incremental tokenized
25
- // autocompletion. Specific auto-completion logic (AJAX, etc)
26
- // belongs in getUpdatedChoices.
27
- //
28
- // Tokenized incremental autocompletion is enabled automatically
29
- // when an autocompleter is instantiated with the 'tokens' option
30
- // in the options parameter, e.g.:
31
- // new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
32
- // will incrementally autocomplete with a comma as the token.
33
- // Additionally, ',' in the above example can be replaced with
34
- // a token array, e.g. { tokens: [',', '\n'] } which
35
- // enables autocompletion on multiple tokens. This is most
36
- // useful when one of the tokens is \n (a newline), as it
37
- // allows smart autocompletion after linebreaks.
38
-
39
- if(typeof Effect == 'undefined')
40
- throw("controls.js requires including script.aculo.us' effects.js library");
41
-
42
- var Autocompleter = { };
43
- Autocompleter.Base = Class.create({
44
- baseInitialize: function(element, update, options) {
45
- element = $(element);
46
- this.element = element;
47
- this.update = $(update);
48
- this.hasFocus = false;
49
- this.changed = false;
50
- this.active = false;
51
- this.index = 0;
52
- this.entryCount = 0;
53
- this.oldElementValue = this.element.value;
54
-
55
- if(this.setOptions)
56
- this.setOptions(options);
57
- else
58
- this.options = options || { };
59
-
60
- this.options.paramName = this.options.paramName || this.element.name;
61
- this.options.tokens = this.options.tokens || [];
62
- this.options.frequency = this.options.frequency || 0.4;
63
- this.options.minChars = this.options.minChars || 1;
64
- this.options.onShow = this.options.onShow ||
65
- function(element, update){
66
- if(!update.style.position || update.style.position=='absolute') {
67
- update.style.position = 'absolute';
68
- Position.clone(element, update, {
69
- setHeight: false,
70
- offsetTop: element.offsetHeight
71
- });
72
- }
73
- Effect.Appear(update,{duration:0.15});
74
- };
75
- this.options.onHide = this.options.onHide ||
76
- function(element, update){ new Effect.Fade(update,{duration:0.15}) };
77
-
78
- if(typeof(this.options.tokens) == 'string')
79
- this.options.tokens = new Array(this.options.tokens);
80
- // Force carriage returns as token delimiters anyway
81
- if (!this.options.tokens.include('\n'))
82
- this.options.tokens.push('\n');
83
-
84
- this.observer = null;
85
-
86
- this.element.setAttribute('autocomplete','off');
87
-
88
- Element.hide(this.update);
89
-
90
- Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
91
- Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
92
- },
93
-
94
- show: function() {
95
- if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
96
- if(!this.iefix &&
97
- (Prototype.Browser.IE) &&
98
- (Element.getStyle(this.update, 'position')=='absolute')) {
99
- new Insertion.After(this.update,
100
- '<iframe id="' + this.update.id + '_iefix" '+
101
- 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
102
- 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
103
- this.iefix = $(this.update.id+'_iefix');
104
- }
105
- if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
106
- },
107
-
108
- fixIEOverlapping: function() {
109
- Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
110
- this.iefix.style.zIndex = 1;
111
- this.update.style.zIndex = 2;
112
- Element.show(this.iefix);
113
- },
114
-
115
- hide: function() {
116
- this.stopIndicator();
117
- if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
118
- if(this.iefix) Element.hide(this.iefix);
119
- },
120
-
121
- startIndicator: function() {
122
- if(this.options.indicator) Element.show(this.options.indicator);
123
- },
124
-
125
- stopIndicator: function() {
126
- if(this.options.indicator) Element.hide(this.options.indicator);
127
- },
128
-
129
- onKeyPress: function(event) {
130
- if(this.active)
131
- switch(event.keyCode) {
132
- case Event.KEY_TAB:
133
- case Event.KEY_RETURN:
134
- this.selectEntry();
135
- Event.stop(event);
136
- case Event.KEY_ESC:
137
- this.hide();
138
- this.active = false;
139
- Event.stop(event);
140
- return;
141
- case Event.KEY_LEFT:
142
- case Event.KEY_RIGHT:
143
- return;
144
- case Event.KEY_UP:
145
- this.markPrevious();
146
- this.render();
147
- Event.stop(event);
148
- return;
149
- case Event.KEY_DOWN:
150
- this.markNext();
151
- this.render();
152
- Event.stop(event);
153
- return;
154
- }
155
- else
156
- if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
157
- (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
158
-
159
- this.changed = true;
160
- this.hasFocus = true;
161
-
162
- if(this.observer) clearTimeout(this.observer);
163
- this.observer =
164
- setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
165
- },
166
-
167
- activate: function() {
168
- this.changed = false;
169
- this.hasFocus = true;
170
- this.getUpdatedChoices();
171
- },
172
-
173
- onHover: function(event) {
174
- var element = Event.findElement(event, 'LI');
175
- if(this.index != element.autocompleteIndex)
176
- {
177
- this.index = element.autocompleteIndex;
178
- this.render();
179
- }
180
- Event.stop(event);
181
- },
182
-
183
- onClick: function(event) {
184
- var element = Event.findElement(event, 'LI');
185
- this.index = element.autocompleteIndex;
186
- this.selectEntry();
187
- this.hide();
188
- },
189
-
190
- onBlur: function(event) {
191
- // needed to make click events working
192
- setTimeout(this.hide.bind(this), 250);
193
- this.hasFocus = false;
194
- this.active = false;
195
- },
196
-
197
- render: function() {
198
- if(this.entryCount > 0) {
199
- for (var i = 0; i < this.entryCount; i++)
200
- this.index==i ?
201
- Element.addClassName(this.getEntry(i),"selected") :
202
- Element.removeClassName(this.getEntry(i),"selected");
203
- if(this.hasFocus) {
204
- this.show();
205
- this.active = true;
206
- }
207
- } else {
208
- this.active = false;
209
- this.hide();
210
- }
211
- },
212
-
213
- markPrevious: function() {
214
- if(this.index > 0) this.index--;
215
- else this.index = this.entryCount-1;
216
- this.getEntry(this.index).scrollIntoView(true);
217
- },
218
-
219
- markNext: function() {
220
- if(this.index < this.entryCount-1) this.index++;
221
- else this.index = 0;
222
- this.getEntry(this.index).scrollIntoView(false);
223
- },
224
-
225
- getEntry: function(index) {
226
- return this.update.firstChild.childNodes[index];
227
- },
228
-
229
- getCurrentEntry: function() {
230
- return this.getEntry(this.index);
231
- },
232
-
233
- selectEntry: function() {
234
- this.active = false;
235
- this.updateElement(this.getCurrentEntry());
236
- },
237
-
238
- updateElement: function(selectedElement) {
239
- if (this.options.updateElement) {
240
- this.options.updateElement(selectedElement);
241
- return;
242
- }
243
- var value = '';
244
- if (this.options.select) {
245
- var nodes = $(selectedElement).select('.' + this.options.select) || [];
246
- if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
247
- } else
248
- value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
249
-
250
- var bounds = this.getTokenBounds();
251
- if (bounds[0] != -1) {
252
- var newValue = this.element.value.substr(0, bounds[0]);
253
- var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
254
- if (whitespace)
255
- newValue += whitespace[0];
256
- this.element.value = newValue + value + this.element.value.substr(bounds[1]);
257
- } else {
258
- this.element.value = value;
259
- }
260
- this.oldElementValue = this.element.value;
261
- this.element.focus();
262
-
263
- if (this.options.afterUpdateElement)
264
- this.options.afterUpdateElement(this.element, selectedElement);
265
- },
266
-
267
- updateChoices: function(choices) {
268
- if(!this.changed && this.hasFocus) {
269
- this.update.innerHTML = choices;
270
- Element.cleanWhitespace(this.update);
271
- Element.cleanWhitespace(this.update.down());
272
-
273
- if(this.update.firstChild && this.update.down().childNodes) {
274
- this.entryCount =
275
- this.update.down().childNodes.length;
276
- for (var i = 0; i < this.entryCount; i++) {
277
- var entry = this.getEntry(i);
278
- entry.autocompleteIndex = i;
279
- this.addObservers(entry);
280
- }
281
- } else {
282
- this.entryCount = 0;
283
- }
284
-
285
- this.stopIndicator();
286
- this.index = 0;
287
-
288
- if(this.entryCount==1 && this.options.autoSelect) {
289
- this.selectEntry();
290
- this.hide();
291
- } else {
292
- this.render();
293
- }
294
- }
295
- },
296
-
297
- addObservers: function(element) {
298
- Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
299
- Event.observe(element, "click", this.onClick.bindAsEventListener(this));
300
- },
301
-
302
- onObserverEvent: function() {
303
- this.changed = false;
304
- this.tokenBounds = null;
305
- if(this.getToken().length>=this.options.minChars) {
306
- this.getUpdatedChoices();
307
- } else {
308
- this.active = false;
309
- this.hide();
310
- }
311
- this.oldElementValue = this.element.value;
312
- },
313
-
314
- getToken: function() {
315
- var bounds = this.getTokenBounds();
316
- return this.element.value.substring(bounds[0], bounds[1]).strip();
317
- },
318
-
319
- getTokenBounds: function() {
320
- if (null != this.tokenBounds) return this.tokenBounds;
321
- var value = this.element.value;
322
- if (value.strip().empty()) return [-1, 0];
323
- var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
324
- var offset = (diff == this.oldElementValue.length ? 1 : 0);
325
- var prevTokenPos = -1, nextTokenPos = value.length;
326
- var tp;
327
- for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
328
- tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
329
- if (tp > prevTokenPos) prevTokenPos = tp;
330
- tp = value.indexOf(this.options.tokens[index], diff + offset);
331
- if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
332
- }
333
- return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
334
- }
335
- });
336
-
337
- Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
338
- var boundary = Math.min(newS.length, oldS.length);
339
- for (var index = 0; index < boundary; ++index)
340
- if (newS[index] != oldS[index])
341
- return index;
342
- return boundary;
343
- };
344
-
345
- Ajax.Autocompleter = Class.create(Autocompleter.Base, {
346
- initialize: function(element, update, url, options) {
347
- this.baseInitialize(element, update, options);
348
- this.options.asynchronous = true;
349
- this.options.onComplete = this.onComplete.bind(this);
350
- this.options.defaultParams = this.options.parameters || null;
351
- this.url = url;
352
- },
353
-
354
- getUpdatedChoices: function() {
355
- this.startIndicator();
356
-
357
- var entry = encodeURIComponent(this.options.paramName) + '=' +
358
- encodeURIComponent(this.getToken());
359
-
360
- this.options.parameters = this.options.callback ?
361
- this.options.callback(this.element, entry) : entry;
362
-
363
- if(this.options.defaultParams)
364
- this.options.parameters += '&' + this.options.defaultParams;
365
-
366
- new Ajax.Request(this.url, this.options);
367
- },
368
-
369
- onComplete: function(request) {
370
- this.updateChoices(request.responseText);
371
- }
372
- });
373
-
374
- // The local array autocompleter. Used when you'd prefer to
375
- // inject an array of autocompletion options into the page, rather
376
- // than sending out Ajax queries, which can be quite slow sometimes.
377
- //
378
- // The constructor takes four parameters. The first two are, as usual,
379
- // the id of the monitored textbox, and id of the autocompletion menu.
380
- // The third is the array you want to autocomplete from, and the fourth
381
- // is the options block.
382
- //
383
- // Extra local autocompletion options:
384
- // - choices - How many autocompletion choices to offer
385
- //
386
- // - partialSearch - If false, the autocompleter will match entered
387
- // text only at the beginning of strings in the
388
- // autocomplete array. Defaults to true, which will
389
- // match text at the beginning of any *word* in the
390
- // strings in the autocomplete array. If you want to
391
- // search anywhere in the string, additionally set
392
- // the option fullSearch to true (default: off).
393
- //
394
- // - fullSsearch - Search anywhere in autocomplete array strings.
395
- //
396
- // - partialChars - How many characters to enter before triggering
397
- // a partial match (unlike minChars, which defines
398
- // how many characters are required to do any match
399
- // at all). Defaults to 2.
400
- //
401
- // - ignoreCase - Whether to ignore case when autocompleting.
402
- // Defaults to true.
403
- //
404
- // It's possible to pass in a custom function as the 'selector'
405
- // option, if you prefer to write your own autocompletion logic.
406
- // In that case, the other options above will not apply unless
407
- // you support them.
408
-
409
- Autocompleter.Local = Class.create(Autocompleter.Base, {
410
- initialize: function(element, update, array, options) {
411
- this.baseInitialize(element, update, options);
412
- this.options.array = array;
413
- },
414
-
415
- getUpdatedChoices: function() {
416
- this.updateChoices(this.options.selector(this));
417
- },
418
-
419
- setOptions: function(options) {
420
- this.options = Object.extend({
421
- choices: 10,
422
- partialSearch: true,
423
- partialChars: 2,
424
- ignoreCase: true,
425
- fullSearch: false,
426
- selector: function(instance) {
427
- var ret = []; // Beginning matches
428
- var partial = []; // Inside matches
429
- var entry = instance.getToken();
430
- var count = 0;
431
-
432
- for (var i = 0; i < instance.options.array.length &&
433
- ret.length < instance.options.choices ; i++) {
434
-
435
- var elem = instance.options.array[i];
436
- var foundPos = instance.options.ignoreCase ?
437
- elem.toLowerCase().indexOf(entry.toLowerCase()) :
438
- elem.indexOf(entry);
439
-
440
- while (foundPos != -1) {
441
- if (foundPos == 0 && elem.length != entry.length) {
442
- ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
443
- elem.substr(entry.length) + "</li>");
444
- break;
445
- } else if (entry.length >= instance.options.partialChars &&
446
- instance.options.partialSearch && foundPos != -1) {
447
- if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
448
- partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
449
- elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
450
- foundPos + entry.length) + "</li>");
451
- break;
452
- }
453
- }
454
-
455
- foundPos = instance.options.ignoreCase ?
456
- elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
457
- elem.indexOf(entry, foundPos + 1);
458
-
459
- }
460
- }
461
- if (partial.length)
462
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
463
- return "<ul>" + ret.join('') + "</ul>";
464
- }
465
- }, options || { });
466
- }
467
- });
468
-
469
- // AJAX in-place editor and collection editor
470
- // Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
471
-
472
- // Use this if you notice weird scrolling problems on some browsers,
473
- // the DOM might be a bit confused when this gets called so do this
474
- // waits 1 ms (with setTimeout) until it does the activation
475
- Field.scrollFreeActivate = function(field) {
476
- setTimeout(function() {
477
- Field.activate(field);
478
- }, 1);
479
- };
480
-
481
- Ajax.InPlaceEditor = Class.create({
482
- initialize: function(element, url, options) {
483
- this.url = url;
484
- this.element = element = $(element);
485
- this.prepareOptions();
486
- this._controls = { };
487
- arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
488
- Object.extend(this.options, options || { });
489
- if (!this.options.formId && this.element.id) {
490
- this.options.formId = this.element.id + '-inplaceeditor';
491
- if ($(this.options.formId))
492
- this.options.formId = '';
493
- }
494
- if (this.options.externalControl)
495
- this.options.externalControl = $(this.options.externalControl);
496
- if (!this.options.externalControl)
497
- this.options.externalControlOnly = false;
498
- this._originalBackground = this.element.getStyle('background-color') || 'transparent';
499
- this.element.title = this.options.clickToEditText;
500
- this._boundCancelHandler = this.handleFormCancellation.bind(this);
501
- this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
502
- this._boundFailureHandler = this.handleAJAXFailure.bind(this);
503
- this._boundSubmitHandler = this.handleFormSubmission.bind(this);
504
- this._boundWrapperHandler = this.wrapUp.bind(this);
505
- this.registerListeners();
506
- },
507
- checkForEscapeOrReturn: function(e) {
508
- if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
509
- if (Event.KEY_ESC == e.keyCode)
510
- this.handleFormCancellation(e);
511
- else if (Event.KEY_RETURN == e.keyCode)
512
- this.handleFormSubmission(e);
513
- },
514
- createControl: function(mode, handler, extraClasses) {
515
- var control = this.options[mode + 'Control'];
516
- var text = this.options[mode + 'Text'];
517
- if ('button' == control) {
518
- var btn = document.createElement('input');
519
- btn.type = 'submit';
520
- btn.value = text;
521
- btn.className = 'editor_' + mode + '_button';
522
- if ('cancel' == mode)
523
- btn.onclick = this._boundCancelHandler;
524
- this._form.appendChild(btn);
525
- this._controls[mode] = btn;
526
- } else if ('link' == control) {
527
- var link = document.createElement('a');
528
- link.href = '#';
529
- link.appendChild(document.createTextNode(text));
530
- link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
531
- link.className = 'editor_' + mode + '_link';
532
- if (extraClasses)
533
- link.className += ' ' + extraClasses;
534
- this._form.appendChild(link);
535
- this._controls[mode] = link;
536
- }
537
- },
538
- createEditField: function() {
539
- var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
540
- var fld;
541
- if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
542
- fld = document.createElement('input');
543
- fld.type = 'text';
544
- var size = this.options.size || this.options.cols || 0;
545
- if (0 < size) fld.size = size;
546
- } else {
547
- fld = document.createElement('textarea');
548
- fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
549
- fld.cols = this.options.cols || 40;
550
- }
551
- fld.name = this.options.paramName;
552
- fld.value = text; // No HTML breaks conversion anymore
553
- fld.className = 'editor_field';
554
- if (this.options.submitOnBlur)
555
- fld.onblur = this._boundSubmitHandler;
556
- this._controls.editor = fld;
557
- if (this.options.loadTextURL)
558
- this.loadExternalText();
559
- this._form.appendChild(this._controls.editor);
560
- },
561
- createForm: function() {
562
- var ipe = this;
563
- function addText(mode, condition) {
564
- var text = ipe.options['text' + mode + 'Controls'];
565
- if (!text || condition === false) return;
566
- ipe._form.appendChild(document.createTextNode(text));
567
- };
568
- this._form = $(document.createElement('form'));
569
- this._form.id = this.options.formId;
570
- this._form.addClassName(this.options.formClassName);
571
- this._form.onsubmit = this._boundSubmitHandler;
572
- this.createEditField();
573
- if ('textarea' == this._controls.editor.tagName.toLowerCase())
574
- this._form.appendChild(document.createElement('br'));
575
- if (this.options.onFormCustomization)
576
- this.options.onFormCustomization(this, this._form);
577
- addText('Before', this.options.okControl || this.options.cancelControl);
578
- this.createControl('ok', this._boundSubmitHandler);
579
- addText('Between', this.options.okControl && this.options.cancelControl);
580
- this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
581
- addText('After', this.options.okControl || this.options.cancelControl);
582
- },
583
- destroy: function() {
584
- if (this._oldInnerHTML)
585
- this.element.innerHTML = this._oldInnerHTML;
586
- this.leaveEditMode();
587
- this.unregisterListeners();
588
- },
589
- enterEditMode: function(e) {
590
- if (this._saving || this._editing) return;
591
- this._editing = true;
592
- this.triggerCallback('onEnterEditMode');
593
- if (this.options.externalControl)
594
- this.options.externalControl.hide();
595
- this.element.hide();
596
- this.createForm();
597
- this.element.parentNode.insertBefore(this._form, this.element);
598
- if (!this.options.loadTextURL)
599
- this.postProcessEditField();
600
- if (e) Event.stop(e);
601
- },
602
- enterHover: function(e) {
603
- if (this.options.hoverClassName)
604
- this.element.addClassName(this.options.hoverClassName);
605
- if (this._saving) return;
606
- this.triggerCallback('onEnterHover');
607
- },
608
- getText: function() {
609
- return this.element.innerHTML.unescapeHTML();
610
- },
611
- handleAJAXFailure: function(transport) {
612
- this.triggerCallback('onFailure', transport);
613
- if (this._oldInnerHTML) {
614
- this.element.innerHTML = this._oldInnerHTML;
615
- this._oldInnerHTML = null;
616
- }
617
- },
618
- handleFormCancellation: function(e) {
619
- this.wrapUp();
620
- if (e) Event.stop(e);
621
- },
622
- handleFormSubmission: function(e) {
623
- var form = this._form;
624
- var value = $F(this._controls.editor);
625
- this.prepareSubmission();
626
- var params = this.options.callback(form, value) || '';
627
- if (Object.isString(params))
628
- params = params.toQueryParams();
629
- params.editorId = this.element.id;
630
- if (this.options.htmlResponse) {
631
- var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
632
- Object.extend(options, {
633
- parameters: params,
634
- onComplete: this._boundWrapperHandler,
635
- onFailure: this._boundFailureHandler
636
- });
637
- new Ajax.Updater({ success: this.element }, this.url, options);
638
- } else {
639
- var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
640
- Object.extend(options, {
641
- parameters: params,
642
- onComplete: this._boundWrapperHandler,
643
- onFailure: this._boundFailureHandler
644
- });
645
- new Ajax.Request(this.url, options);
646
- }
647
- if (e) Event.stop(e);
648
- },
649
- leaveEditMode: function() {
650
- this.element.removeClassName(this.options.savingClassName);
651
- this.removeForm();
652
- this.leaveHover();
653
- this.element.style.backgroundColor = this._originalBackground;
654
- this.element.show();
655
- if (this.options.externalControl)
656
- this.options.externalControl.show();
657
- this._saving = false;
658
- this._editing = false;
659
- this._oldInnerHTML = null;
660
- this.triggerCallback('onLeaveEditMode');
661
- },
662
- leaveHover: function(e) {
663
- if (this.options.hoverClassName)
664
- this.element.removeClassName(this.options.hoverClassName);
665
- if (this._saving) return;
666
- this.triggerCallback('onLeaveHover');
667
- },
668
- loadExternalText: function() {
669
- this._form.addClassName(this.options.loadingClassName);
670
- this._controls.editor.disabled = true;
671
- var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
672
- Object.extend(options, {
673
- parameters: 'editorId=' + encodeURIComponent(this.element.id),
674
- onComplete: Prototype.emptyFunction,
675
- onSuccess: function(transport) {
676
- this._form.removeClassName(this.options.loadingClassName);
677
- var text = transport.responseText;
678
- if (this.options.stripLoadedTextTags)
679
- text = text.stripTags();
680
- this._controls.editor.value = text;
681
- this._controls.editor.disabled = false;
682
- this.postProcessEditField();
683
- }.bind(this),
684
- onFailure: this._boundFailureHandler
685
- });
686
- new Ajax.Request(this.options.loadTextURL, options);
687
- },
688
- postProcessEditField: function() {
689
- var fpc = this.options.fieldPostCreation;
690
- if (fpc)
691
- $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
692
- },
693
- prepareOptions: function() {
694
- this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
695
- Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
696
- [this._extraDefaultOptions].flatten().compact().each(function(defs) {
697
- Object.extend(this.options, defs);
698
- }.bind(this));
699
- },
700
- prepareSubmission: function() {
701
- this._saving = true;
702
- this.removeForm();
703
- this.leaveHover();
704
- this.showSaving();
705
- },
706
- registerListeners: function() {
707
- this._listeners = { };
708
- var listener;
709
- $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
710
- listener = this[pair.value].bind(this);
711
- this._listeners[pair.key] = listener;
712
- if (!this.options.externalControlOnly)
713
- this.element.observe(pair.key, listener);
714
- if (this.options.externalControl)
715
- this.options.externalControl.observe(pair.key, listener);
716
- }.bind(this));
717
- },
718
- removeForm: function() {
719
- if (!this._form) return;
720
- this._form.remove();
721
- this._form = null;
722
- this._controls = { };
723
- },
724
- showSaving: function() {
725
- this._oldInnerHTML = this.element.innerHTML;
726
- this.element.innerHTML = this.options.savingText;
727
- this.element.addClassName(this.options.savingClassName);
728
- this.element.style.backgroundColor = this._originalBackground;
729
- this.element.show();
730
- },
731
- triggerCallback: function(cbName, arg) {
732
- if ('function' == typeof this.options[cbName]) {
733
- this.options[cbName](this, arg);
734
- }
735
- },
736
- unregisterListeners: function() {
737
- $H(this._listeners).each(function(pair) {
738
- if (!this.options.externalControlOnly)
739
- this.element.stopObserving(pair.key, pair.value);
740
- if (this.options.externalControl)
741
- this.options.externalControl.stopObserving(pair.key, pair.value);
742
- }.bind(this));
743
- },
744
- wrapUp: function(transport) {
745
- this.leaveEditMode();
746
- // Can't use triggerCallback due to backward compatibility: requires
747
- // binding + direct element
748
- this._boundComplete(transport, this.element);
749
- }
750
- });
751
-
752
- Object.extend(Ajax.InPlaceEditor.prototype, {
753
- dispose: Ajax.InPlaceEditor.prototype.destroy
754
- });
755
-
756
- Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
757
- initialize: function($super, element, url, options) {
758
- this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
759
- $super(element, url, options);
760
- },
761
-
762
- createEditField: function() {
763
- var list = document.createElement('select');
764
- list.name = this.options.paramName;
765
- list.size = 1;
766
- this._controls.editor = list;
767
- this._collection = this.options.collection || [];
768
- if (this.options.loadCollectionURL)
769
- this.loadCollection();
770
- else
771
- this.checkForExternalText();
772
- this._form.appendChild(this._controls.editor);
773
- },
774
-
775
- loadCollection: function() {
776
- this._form.addClassName(this.options.loadingClassName);
777
- this.showLoadingText(this.options.loadingCollectionText);
778
- var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
779
- Object.extend(options, {
780
- parameters: 'editorId=' + encodeURIComponent(this.element.id),
781
- onComplete: Prototype.emptyFunction,
782
- onSuccess: function(transport) {
783
- var js = transport.responseText.strip();
784
- if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
785
- throw('Server returned an invalid collection representation.');
786
- this._collection = eval(js);
787
- this.checkForExternalText();
788
- }.bind(this),
789
- onFailure: this.onFailure
790
- });
791
- new Ajax.Request(this.options.loadCollectionURL, options);
792
- },
793
-
794
- showLoadingText: function(text) {
795
- this._controls.editor.disabled = true;
796
- var tempOption = this._controls.editor.firstChild;
797
- if (!tempOption) {
798
- tempOption = document.createElement('option');
799
- tempOption.value = '';
800
- this._controls.editor.appendChild(tempOption);
801
- tempOption.selected = true;
802
- }
803
- tempOption.update((text || '').stripScripts().stripTags());
804
- },
805
-
806
- checkForExternalText: function() {
807
- this._text = this.getText();
808
- if (this.options.loadTextURL)
809
- this.loadExternalText();
810
- else
811
- this.buildOptionList();
812
- },
813
-
814
- loadExternalText: function() {
815
- this.showLoadingText(this.options.loadingText);
816
- var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
817
- Object.extend(options, {
818
- parameters: 'editorId=' + encodeURIComponent(this.element.id),
819
- onComplete: Prototype.emptyFunction,
820
- onSuccess: function(transport) {
821
- this._text = transport.responseText.strip();
822
- this.buildOptionList();
823
- }.bind(this),
824
- onFailure: this.onFailure
825
- });
826
- new Ajax.Request(this.options.loadTextURL, options);
827
- },
828
-
829
- buildOptionList: function() {
830
- this._form.removeClassName(this.options.loadingClassName);
831
- this._collection = this._collection.map(function(entry) {
832
- return 2 === entry.length ? entry : [entry, entry].flatten();
833
- });
834
- var marker = ('value' in this.options) ? this.options.value : this._text;
835
- var textFound = this._collection.any(function(entry) {
836
- return entry[0] == marker;
837
- }.bind(this));
838
- this._controls.editor.update('');
839
- var option;
840
- this._collection.each(function(entry, index) {
841
- option = document.createElement('option');
842
- option.value = entry[0];
843
- option.selected = textFound ? entry[0] == marker : 0 == index;
844
- option.appendChild(document.createTextNode(entry[1]));
845
- this._controls.editor.appendChild(option);
846
- }.bind(this));
847
- this._controls.editor.disabled = false;
848
- Field.scrollFreeActivate(this._controls.editor);
849
- }
850
- });
851
-
852
- //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
853
- //**** This only exists for a while, in order to let ****
854
- //**** users adapt to the new API. Read up on the new ****
855
- //**** API and convert your code to it ASAP! ****
856
-
857
- Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
858
- if (!options) return;
859
- function fallback(name, expr) {
860
- if (name in options || expr === undefined) return;
861
- options[name] = expr;
862
- };
863
- fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
864
- options.cancelLink == options.cancelButton == false ? false : undefined)));
865
- fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
866
- options.okLink == options.okButton == false ? false : undefined)));
867
- fallback('highlightColor', options.highlightcolor);
868
- fallback('highlightEndColor', options.highlightendcolor);
869
- };
870
-
871
- Object.extend(Ajax.InPlaceEditor, {
872
- DefaultOptions: {
873
- ajaxOptions: { },
874
- autoRows: 3, // Use when multi-line w/ rows == 1
875
- cancelControl: 'link', // 'link'|'button'|false
876
- cancelText: 'cancel',
877
- clickToEditText: 'Click to edit',
878
- externalControl: null, // id|elt
879
- externalControlOnly: false,
880
- fieldPostCreation: 'activate', // 'activate'|'focus'|false
881
- formClassName: 'inplaceeditor-form',
882
- formId: null, // id|elt
883
- highlightColor: '#ffff99',
884
- highlightEndColor: '#ffffff',
885
- hoverClassName: '',
886
- htmlResponse: true,
887
- loadingClassName: 'inplaceeditor-loading',
888
- loadingText: 'Loading...',
889
- okControl: 'button', // 'link'|'button'|false
890
- okText: 'ok',
891
- paramName: 'value',
892
- rows: 1, // If 1 and multi-line, uses autoRows
893
- savingClassName: 'inplaceeditor-saving',
894
- savingText: 'Saving...',
895
- size: 0,
896
- stripLoadedTextTags: false,
897
- submitOnBlur: false,
898
- textAfterControls: '',
899
- textBeforeControls: '',
900
- textBetweenControls: ''
901
- },
902
- DefaultCallbacks: {
903
- callback: function(form) {
904
- return Form.serialize(form);
905
- },
906
- onComplete: function(transport, element) {
907
- // For backward compatibility, this one is bound to the IPE, and passes
908
- // the element directly. It was too often customized, so we don't break it.
909
- new Effect.Highlight(element, {
910
- startcolor: this.options.highlightColor, keepBackgroundImage: true });
911
- },
912
- onEnterEditMode: null,
913
- onEnterHover: function(ipe) {
914
- ipe.element.style.backgroundColor = ipe.options.highlightColor;
915
- if (ipe._effect)
916
- ipe._effect.cancel();
917
- },
918
- onFailure: function(transport, ipe) {
919
- alert('Error communication with the server: ' + transport.responseText.stripTags());
920
- },
921
- onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
922
- onLeaveEditMode: null,
923
- onLeaveHover: function(ipe) {
924
- ipe._effect = new Effect.Highlight(ipe.element, {
925
- startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
926
- restorecolor: ipe._originalBackground, keepBackgroundImage: true
927
- });
928
- }
929
- },
930
- Listeners: {
931
- click: 'enterEditMode',
932
- keydown: 'checkForEscapeOrReturn',
933
- mouseover: 'enterHover',
934
- mouseout: 'leaveHover'
935
- }
936
- });
937
-
938
- Ajax.InPlaceCollectionEditor.DefaultOptions = {
939
- loadingCollectionText: 'Loading options...'
940
- };
941
-
942
- // Delayed observer, like Form.Element.Observer,
943
- // but waits for delay after last key input
944
- // Ideal for live-search fields
945
-
946
- Form.Element.DelayedObserver = Class.create({
947
- initialize: function(element, delay, callback) {
948
- this.delay = delay || 0.5;
949
- this.element = $(element);
950
- this.callback = callback;
951
- this.timer = null;
952
- this.lastValue = $F(this.element);
953
- Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
954
- },
955
- delayedListener: function(event) {
956
- if(this.lastValue == $F(this.element)) return;
957
- if(this.timer) clearTimeout(this.timer);
958
- this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
959
- this.lastValue = $F(this.element);
960
- },
961
- onTimerEvent: function() {
962
- this.timer = null;
963
- this.callback(this.element, $F(this.element));
964
- }
965
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/dragdrop.js DELETED
@@ -1,974 +0,0 @@
1
- // script.aculo.us dragdrop.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- //
5
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
6
- // For details, see the script.aculo.us web site: http://script.aculo.us/
7
-
8
- if(Object.isUndefined(Effect))
9
- throw("dragdrop.js requires including script.aculo.us' effects.js library");
10
-
11
- var Droppables = {
12
- drops: [],
13
-
14
- remove: function(element) {
15
- this.drops = this.drops.reject(function(d) { return d.element==$(element) });
16
- },
17
-
18
- add: function(element) {
19
- element = $(element);
20
- var options = Object.extend({
21
- greedy: true,
22
- hoverclass: null,
23
- tree: false
24
- }, arguments[1] || { });
25
-
26
- // cache containers
27
- if(options.containment) {
28
- options._containers = [];
29
- var containment = options.containment;
30
- if(Object.isArray(containment)) {
31
- containment.each( function(c) { options._containers.push($(c)) });
32
- } else {
33
- options._containers.push($(containment));
34
- }
35
- }
36
-
37
- if(options.accept) options.accept = [options.accept].flatten();
38
-
39
- Element.makePositioned(element); // fix IE
40
- options.element = element;
41
-
42
- this.drops.push(options);
43
- },
44
-
45
- findDeepestChild: function(drops) {
46
- deepest = drops[0];
47
-
48
- for (i = 1; i < drops.length; ++i)
49
- if (Element.isParent(drops[i].element, deepest.element))
50
- deepest = drops[i];
51
-
52
- return deepest;
53
- },
54
-
55
- isContained: function(element, drop) {
56
- var containmentNode;
57
- if(drop.tree) {
58
- containmentNode = element.treeNode;
59
- } else {
60
- containmentNode = element.parentNode;
61
- }
62
- return drop._containers.detect(function(c) { return containmentNode == c });
63
- },
64
-
65
- isAffected: function(point, element, drop) {
66
- return (
67
- (drop.element!=element) &&
68
- ((!drop._containers) ||
69
- this.isContained(element, drop)) &&
70
- ((!drop.accept) ||
71
- (Element.classNames(element).detect(
72
- function(v) { return drop.accept.include(v) } ) )) &&
73
- Position.within(drop.element, point[0], point[1]) );
74
- },
75
-
76
- deactivate: function(drop) {
77
- if(drop.hoverclass)
78
- Element.removeClassName(drop.element, drop.hoverclass);
79
- this.last_active = null;
80
- },
81
-
82
- activate: function(drop) {
83
- if(drop.hoverclass)
84
- Element.addClassName(drop.element, drop.hoverclass);
85
- this.last_active = drop;
86
- },
87
-
88
- show: function(point, element) {
89
- if(!this.drops.length) return;
90
- var drop, affected = [];
91
-
92
- this.drops.each( function(drop) {
93
- if(Droppables.isAffected(point, element, drop))
94
- affected.push(drop);
95
- });
96
-
97
- if(affected.length>0)
98
- drop = Droppables.findDeepestChild(affected);
99
-
100
- if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
101
- if (drop) {
102
- Position.within(drop.element, point[0], point[1]);
103
- if(drop.onHover)
104
- drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
105
-
106
- if (drop != this.last_active) Droppables.activate(drop);
107
- }
108
- },
109
-
110
- fire: function(event, element) {
111
- if(!this.last_active) return;
112
- Position.prepare();
113
-
114
- if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
115
- if (this.last_active.onDrop) {
116
- this.last_active.onDrop(element, this.last_active.element, event);
117
- return true;
118
- }
119
- },
120
-
121
- reset: function() {
122
- if(this.last_active)
123
- this.deactivate(this.last_active);
124
- }
125
- };
126
-
127
- var Draggables = {
128
- drags: [],
129
- observers: [],
130
-
131
- register: function(draggable) {
132
- if(this.drags.length == 0) {
133
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
134
- this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
135
- this.eventKeypress = this.keyPress.bindAsEventListener(this);
136
-
137
- Event.observe(document, "mouseup", this.eventMouseUp);
138
- Event.observe(document, "mousemove", this.eventMouseMove);
139
- Event.observe(document, "keypress", this.eventKeypress);
140
- }
141
- this.drags.push(draggable);
142
- },
143
-
144
- unregister: function(draggable) {
145
- this.drags = this.drags.reject(function(d) { return d==draggable });
146
- if(this.drags.length == 0) {
147
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
148
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
149
- Event.stopObserving(document, "keypress", this.eventKeypress);
150
- }
151
- },
152
-
153
- activate: function(draggable) {
154
- if(draggable.options.delay) {
155
- this._timeout = setTimeout(function() {
156
- Draggables._timeout = null;
157
- window.focus();
158
- Draggables.activeDraggable = draggable;
159
- }.bind(this), draggable.options.delay);
160
- } else {
161
- window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
162
- this.activeDraggable = draggable;
163
- }
164
- },
165
-
166
- deactivate: function() {
167
- this.activeDraggable = null;
168
- },
169
-
170
- updateDrag: function(event) {
171
- if(!this.activeDraggable) return;
172
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
173
- // Mozilla-based browsers fire successive mousemove events with
174
- // the same coordinates, prevent needless redrawing (moz bug?)
175
- if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
176
- this._lastPointer = pointer;
177
-
178
- this.activeDraggable.updateDrag(event, pointer);
179
- },
180
-
181
- endDrag: function(event) {
182
- if(this._timeout) {
183
- clearTimeout(this._timeout);
184
- this._timeout = null;
185
- }
186
- if(!this.activeDraggable) return;
187
- this._lastPointer = null;
188
- this.activeDraggable.endDrag(event);
189
- this.activeDraggable = null;
190
- },
191
-
192
- keyPress: function(event) {
193
- if(this.activeDraggable)
194
- this.activeDraggable.keyPress(event);
195
- },
196
-
197
- addObserver: function(observer) {
198
- this.observers.push(observer);
199
- this._cacheObserverCallbacks();
200
- },
201
-
202
- removeObserver: function(element) { // element instead of observer fixes mem leaks
203
- this.observers = this.observers.reject( function(o) { return o.element==element });
204
- this._cacheObserverCallbacks();
205
- },
206
-
207
- notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
208
- if(this[eventName+'Count'] > 0)
209
- this.observers.each( function(o) {
210
- if(o[eventName]) o[eventName](eventName, draggable, event);
211
- });
212
- if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
213
- },
214
-
215
- _cacheObserverCallbacks: function() {
216
- ['onStart','onEnd','onDrag'].each( function(eventName) {
217
- Draggables[eventName+'Count'] = Draggables.observers.select(
218
- function(o) { return o[eventName]; }
219
- ).length;
220
- });
221
- }
222
- };
223
-
224
- /*--------------------------------------------------------------------------*/
225
-
226
- var Draggable = Class.create({
227
- initialize: function(element) {
228
- var defaults = {
229
- handle: false,
230
- reverteffect: function(element, top_offset, left_offset) {
231
- var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
232
- new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
233
- queue: {scope:'_draggable', position:'end'}
234
- });
235
- },
236
- endeffect: function(element) {
237
- var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
238
- new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
239
- queue: {scope:'_draggable', position:'end'},
240
- afterFinish: function(){
241
- Draggable._dragging[element] = false
242
- }
243
- });
244
- },
245
- zindex: 1000,
246
- revert: false,
247
- quiet: false,
248
- scroll: false,
249
- scrollSensitivity: 20,
250
- scrollSpeed: 15,
251
- snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
252
- delay: 0
253
- };
254
-
255
- if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
256
- Object.extend(defaults, {
257
- starteffect: function(element) {
258
- element._opacity = Element.getOpacity(element);
259
- Draggable._dragging[element] = true;
260
- new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
261
- }
262
- });
263
-
264
- var options = Object.extend(defaults, arguments[1] || { });
265
-
266
- this.element = $(element);
267
-
268
- if(options.handle && Object.isString(options.handle))
269
- this.handle = this.element.down('.'+options.handle, 0);
270
-
271
- if(!this.handle) this.handle = $(options.handle);
272
- if(!this.handle) this.handle = this.element;
273
-
274
- if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
275
- options.scroll = $(options.scroll);
276
- this._isScrollChild = Element.childOf(this.element, options.scroll);
277
- }
278
-
279
- Element.makePositioned(this.element); // fix IE
280
-
281
- this.options = options;
282
- this.dragging = false;
283
-
284
- this.eventMouseDown = this.initDrag.bindAsEventListener(this);
285
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
286
-
287
- Draggables.register(this);
288
- },
289
-
290
- destroy: function() {
291
- Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
292
- Draggables.unregister(this);
293
- },
294
-
295
- currentDelta: function() {
296
- return([
297
- parseInt(Element.getStyle(this.element,'left') || '0'),
298
- parseInt(Element.getStyle(this.element,'top') || '0')]);
299
- },
300
-
301
- initDrag: function(event) {
302
- if(!Object.isUndefined(Draggable._dragging[this.element]) &&
303
- Draggable._dragging[this.element]) return;
304
- if(Event.isLeftClick(event)) {
305
- // abort on form elements, fixes a Firefox issue
306
- var src = Event.element(event);
307
- if((tag_name = src.tagName.toUpperCase()) && (
308
- tag_name=='INPUT' ||
309
- tag_name=='SELECT' ||
310
- tag_name=='OPTION' ||
311
- tag_name=='BUTTON' ||
312
- tag_name=='TEXTAREA')) return;
313
-
314
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
315
- var pos = this.element.cumulativeOffset();
316
- this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
317
-
318
- Draggables.activate(this);
319
- Event.stop(event);
320
- }
321
- },
322
-
323
- startDrag: function(event) {
324
- this.dragging = true;
325
- if(!this.delta)
326
- this.delta = this.currentDelta();
327
-
328
- if(this.options.zindex) {
329
- this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
330
- this.element.style.zIndex = this.options.zindex;
331
- }
332
-
333
- if(this.options.ghosting) {
334
- this._clone = this.element.cloneNode(true);
335
- this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
336
- if (!this._originallyAbsolute)
337
- Position.absolutize(this.element);
338
- this.element.parentNode.insertBefore(this._clone, this.element);
339
- }
340
-
341
- if(this.options.scroll) {
342
- if (this.options.scroll == window) {
343
- var where = this._getWindowScroll(this.options.scroll);
344
- this.originalScrollLeft = where.left;
345
- this.originalScrollTop = where.top;
346
- } else {
347
- this.originalScrollLeft = this.options.scroll.scrollLeft;
348
- this.originalScrollTop = this.options.scroll.scrollTop;
349
- }
350
- }
351
-
352
- Draggables.notify('onStart', this, event);
353
-
354
- if(this.options.starteffect) this.options.starteffect(this.element);
355
- },
356
-
357
- updateDrag: function(event, pointer) {
358
- if(!this.dragging) this.startDrag(event);
359
-
360
- if(!this.options.quiet){
361
- Position.prepare();
362
- Droppables.show(pointer, this.element);
363
- }
364
-
365
- Draggables.notify('onDrag', this, event);
366
-
367
- this.draw(pointer);
368
- if(this.options.change) this.options.change(this);
369
-
370
- if(this.options.scroll) {
371
- this.stopScrolling();
372
-
373
- var p;
374
- if (this.options.scroll == window) {
375
- with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
376
- } else {
377
- p = Position.page(this.options.scroll).toArray();
378
- p[0] += this.options.scroll.scrollLeft + Position.deltaX;
379
- p[1] += this.options.scroll.scrollTop + Position.deltaY;
380
- p.push(p[0]+this.options.scroll.offsetWidth);
381
- p.push(p[1]+this.options.scroll.offsetHeight);
382
- }
383
- var speed = [0,0];
384
- if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
385
- if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
386
- if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
387
- if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
388
- this.startScrolling(speed);
389
- }
390
-
391
- // fix AppleWebKit rendering
392
- if(Prototype.Browser.WebKit) window.scrollBy(0,0);
393
-
394
- Event.stop(event);
395
- },
396
-
397
- finishDrag: function(event, success) {
398
- this.dragging = false;
399
-
400
- if(this.options.quiet){
401
- Position.prepare();
402
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
403
- Droppables.show(pointer, this.element);
404
- }
405
-
406
- if(this.options.ghosting) {
407
- if (!this._originallyAbsolute)
408
- Position.relativize(this.element);
409
- delete this._originallyAbsolute;
410
- Element.remove(this._clone);
411
- this._clone = null;
412
- }
413
-
414
- var dropped = false;
415
- if(success) {
416
- dropped = Droppables.fire(event, this.element);
417
- if (!dropped) dropped = false;
418
- }
419
- if(dropped && this.options.onDropped) this.options.onDropped(this.element);
420
- Draggables.notify('onEnd', this, event);
421
-
422
- var revert = this.options.revert;
423
- if(revert && Object.isFunction(revert)) revert = revert(this.element);
424
-
425
- var d = this.currentDelta();
426
- if(revert && this.options.reverteffect) {
427
- if (dropped == 0 || revert != 'failure')
428
- this.options.reverteffect(this.element,
429
- d[1]-this.delta[1], d[0]-this.delta[0]);
430
- } else {
431
- this.delta = d;
432
- }
433
-
434
- if(this.options.zindex)
435
- this.element.style.zIndex = this.originalZ;
436
-
437
- if(this.options.endeffect)
438
- this.options.endeffect(this.element);
439
-
440
- Draggables.deactivate(this);
441
- Droppables.reset();
442
- },
443
-
444
- keyPress: function(event) {
445
- if(event.keyCode!=Event.KEY_ESC) return;
446
- this.finishDrag(event, false);
447
- Event.stop(event);
448
- },
449
-
450
- endDrag: function(event) {
451
- if(!this.dragging) return;
452
- this.stopScrolling();
453
- this.finishDrag(event, true);
454
- Event.stop(event);
455
- },
456
-
457
- draw: function(point) {
458
- var pos = this.element.cumulativeOffset();
459
- if(this.options.ghosting) {
460
- var r = Position.realOffset(this.element);
461
- pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
462
- }
463
-
464
- var d = this.currentDelta();
465
- pos[0] -= d[0]; pos[1] -= d[1];
466
-
467
- if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
468
- pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
469
- pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
470
- }
471
-
472
- var p = [0,1].map(function(i){
473
- return (point[i]-pos[i]-this.offset[i])
474
- }.bind(this));
475
-
476
- if(this.options.snap) {
477
- if(Object.isFunction(this.options.snap)) {
478
- p = this.options.snap(p[0],p[1],this);
479
- } else {
480
- if(Object.isArray(this.options.snap)) {
481
- p = p.map( function(v, i) {
482
- return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
483
- } else {
484
- p = p.map( function(v) {
485
- return (v/this.options.snap).round()*this.options.snap }.bind(this));
486
- }
487
- }}
488
-
489
- var style = this.element.style;
490
- if((!this.options.constraint) || (this.options.constraint=='horizontal'))
491
- style.left = p[0] + "px";
492
- if((!this.options.constraint) || (this.options.constraint=='vertical'))
493
- style.top = p[1] + "px";
494
-
495
- if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
496
- },
497
-
498
- stopScrolling: function() {
499
- if(this.scrollInterval) {
500
- clearInterval(this.scrollInterval);
501
- this.scrollInterval = null;
502
- Draggables._lastScrollPointer = null;
503
- }
504
- },
505
-
506
- startScrolling: function(speed) {
507
- if(!(speed[0] || speed[1])) return;
508
- this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
509
- this.lastScrolled = new Date();
510
- this.scrollInterval = setInterval(this.scroll.bind(this), 10);
511
- },
512
-
513
- scroll: function() {
514
- var current = new Date();
515
- var delta = current - this.lastScrolled;
516
- this.lastScrolled = current;
517
- if(this.options.scroll == window) {
518
- with (this._getWindowScroll(this.options.scroll)) {
519
- if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
520
- var d = delta / 1000;
521
- this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
522
- }
523
- }
524
- } else {
525
- this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
526
- this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
527
- }
528
-
529
- Position.prepare();
530
- Droppables.show(Draggables._lastPointer, this.element);
531
- Draggables.notify('onDrag', this);
532
- if (this._isScrollChild) {
533
- Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
534
- Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
535
- Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
536
- if (Draggables._lastScrollPointer[0] < 0)
537
- Draggables._lastScrollPointer[0] = 0;
538
- if (Draggables._lastScrollPointer[1] < 0)
539
- Draggables._lastScrollPointer[1] = 0;
540
- this.draw(Draggables._lastScrollPointer);
541
- }
542
-
543
- if(this.options.change) this.options.change(this);
544
- },
545
-
546
- _getWindowScroll: function(w) {
547
- var T, L, W, H;
548
- with (w.document) {
549
- if (w.document.documentElement && documentElement.scrollTop) {
550
- T = documentElement.scrollTop;
551
- L = documentElement.scrollLeft;
552
- } else if (w.document.body) {
553
- T = body.scrollTop;
554
- L = body.scrollLeft;
555
- }
556
- if (w.innerWidth) {
557
- W = w.innerWidth;
558
- H = w.innerHeight;
559
- } else if (w.document.documentElement && documentElement.clientWidth) {
560
- W = documentElement.clientWidth;
561
- H = documentElement.clientHeight;
562
- } else {
563
- W = body.offsetWidth;
564
- H = body.offsetHeight;
565
- }
566
- }
567
- return { top: T, left: L, width: W, height: H };
568
- }
569
- });
570
-
571
- Draggable._dragging = { };
572
-
573
- /*--------------------------------------------------------------------------*/
574
-
575
- var SortableObserver = Class.create({
576
- initialize: function(element, observer) {
577
- this.element = $(element);
578
- this.observer = observer;
579
- this.lastValue = Sortable.serialize(this.element);
580
- },
581
-
582
- onStart: function() {
583
- this.lastValue = Sortable.serialize(this.element);
584
- },
585
-
586
- onEnd: function() {
587
- Sortable.unmark();
588
- if(this.lastValue != Sortable.serialize(this.element))
589
- this.observer(this.element)
590
- }
591
- });
592
-
593
- var Sortable = {
594
- SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
595
-
596
- sortables: { },
597
-
598
- _findRootElement: function(element) {
599
- while (element.tagName.toUpperCase() != "BODY") {
600
- if(element.id && Sortable.sortables[element.id]) return element;
601
- element = element.parentNode;
602
- }
603
- },
604
-
605
- options: function(element) {
606
- element = Sortable._findRootElement($(element));
607
- if(!element) return;
608
- return Sortable.sortables[element.id];
609
- },
610
-
611
- destroy: function(element){
612
- element = $(element);
613
- var s = Sortable.sortables[element.id];
614
-
615
- if(s) {
616
- Draggables.removeObserver(s.element);
617
- s.droppables.each(function(d){ Droppables.remove(d) });
618
- s.draggables.invoke('destroy');
619
-
620
- delete Sortable.sortables[s.element.id];
621
- }
622
- },
623
-
624
- create: function(element) {
625
- element = $(element);
626
- var options = Object.extend({
627
- element: element,
628
- tag: 'li', // assumes li children, override with tag: 'tagname'
629
- dropOnEmpty: false,
630
- tree: false,
631
- treeTag: 'ul',
632
- overlap: 'vertical', // one of 'vertical', 'horizontal'
633
- constraint: 'vertical', // one of 'vertical', 'horizontal', false
634
- containment: element, // also takes array of elements (or id's); or false
635
- handle: false, // or a CSS class
636
- only: false,
637
- delay: 0,
638
- hoverclass: null,
639
- ghosting: false,
640
- quiet: false,
641
- scroll: false,
642
- scrollSensitivity: 20,
643
- scrollSpeed: 15,
644
- format: this.SERIALIZE_RULE,
645
-
646
- // these take arrays of elements or ids and can be
647
- // used for better initialization performance
648
- elements: false,
649
- handles: false,
650
-
651
- onChange: Prototype.emptyFunction,
652
- onUpdate: Prototype.emptyFunction
653
- }, arguments[1] || { });
654
-
655
- // clear any old sortable with same element
656
- this.destroy(element);
657
-
658
- // build options for the draggables
659
- var options_for_draggable = {
660
- revert: true,
661
- quiet: options.quiet,
662
- scroll: options.scroll,
663
- scrollSpeed: options.scrollSpeed,
664
- scrollSensitivity: options.scrollSensitivity,
665
- delay: options.delay,
666
- ghosting: options.ghosting,
667
- constraint: options.constraint,
668
- handle: options.handle };
669
-
670
- if(options.starteffect)
671
- options_for_draggable.starteffect = options.starteffect;
672
-
673
- if(options.reverteffect)
674
- options_for_draggable.reverteffect = options.reverteffect;
675
- else
676
- if(options.ghosting) options_for_draggable.reverteffect = function(element) {
677
- element.style.top = 0;
678
- element.style.left = 0;
679
- };
680
-
681
- if(options.endeffect)
682
- options_for_draggable.endeffect = options.endeffect;
683
-
684
- if(options.zindex)
685
- options_for_draggable.zindex = options.zindex;
686
-
687
- // build options for the droppables
688
- var options_for_droppable = {
689
- overlap: options.overlap,
690
- containment: options.containment,
691
- tree: options.tree,
692
- hoverclass: options.hoverclass,
693
- onHover: Sortable.onHover
694
- };
695
-
696
- var options_for_tree = {
697
- onHover: Sortable.onEmptyHover,
698
- overlap: options.overlap,
699
- containment: options.containment,
700
- hoverclass: options.hoverclass
701
- };
702
-
703
- // fix for gecko engine
704
- Element.cleanWhitespace(element);
705
-
706
- options.draggables = [];
707
- options.droppables = [];
708
-
709
- // drop on empty handling
710
- if(options.dropOnEmpty || options.tree) {
711
- Droppables.add(element, options_for_tree);
712
- options.droppables.push(element);
713
- }
714
-
715
- (options.elements || this.findElements(element, options) || []).each( function(e,i) {
716
- var handle = options.handles ? $(options.handles[i]) :
717
- (options.handle ? $(e).select('.' + options.handle)[0] : e);
718
- options.draggables.push(
719
- new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
720
- Droppables.add(e, options_for_droppable);
721
- if(options.tree) e.treeNode = element;
722
- options.droppables.push(e);
723
- });
724
-
725
- if(options.tree) {
726
- (Sortable.findTreeElements(element, options) || []).each( function(e) {
727
- Droppables.add(e, options_for_tree);
728
- e.treeNode = element;
729
- options.droppables.push(e);
730
- });
731
- }
732
-
733
- // keep reference
734
- this.sortables[element.identify()] = options;
735
-
736
- // for onupdate
737
- Draggables.addObserver(new SortableObserver(element, options.onUpdate));
738
-
739
- },
740
-
741
- // return all suitable-for-sortable elements in a guaranteed order
742
- findElements: function(element, options) {
743
- return Element.findChildren(
744
- element, options.only, options.tree ? true : false, options.tag);
745
- },
746
-
747
- findTreeElements: function(element, options) {
748
- return Element.findChildren(
749
- element, options.only, options.tree ? true : false, options.treeTag);
750
- },
751
-
752
- onHover: function(element, dropon, overlap) {
753
- if(Element.isParent(dropon, element)) return;
754
-
755
- if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
756
- return;
757
- } else if(overlap>0.5) {
758
- Sortable.mark(dropon, 'before');
759
- if(dropon.previousSibling != element) {
760
- var oldParentNode = element.parentNode;
761
- element.style.visibility = "hidden"; // fix gecko rendering
762
- dropon.parentNode.insertBefore(element, dropon);
763
- if(dropon.parentNode!=oldParentNode)
764
- Sortable.options(oldParentNode).onChange(element);
765
- Sortable.options(dropon.parentNode).onChange(element);
766
- }
767
- } else {
768
- Sortable.mark(dropon, 'after');
769
- var nextElement = dropon.nextSibling || null;
770
- if(nextElement != element) {
771
- var oldParentNode = element.parentNode;
772
- element.style.visibility = "hidden"; // fix gecko rendering
773
- dropon.parentNode.insertBefore(element, nextElement);
774
- if(dropon.parentNode!=oldParentNode)
775
- Sortable.options(oldParentNode).onChange(element);
776
- Sortable.options(dropon.parentNode).onChange(element);
777
- }
778
- }
779
- },
780
-
781
- onEmptyHover: function(element, dropon, overlap) {
782
- var oldParentNode = element.parentNode;
783
- var droponOptions = Sortable.options(dropon);
784
-
785
- if(!Element.isParent(dropon, element)) {
786
- var index;
787
-
788
- var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
789
- var child = null;
790
-
791
- if(children) {
792
- var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
793
-
794
- for (index = 0; index < children.length; index += 1) {
795
- if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
796
- offset -= Element.offsetSize (children[index], droponOptions.overlap);
797
- } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
798
- child = index + 1 < children.length ? children[index + 1] : null;
799
- break;
800
- } else {
801
- child = children[index];
802
- break;
803
- }
804
- }
805
- }
806
-
807
- dropon.insertBefore(element, child);
808
-
809
- Sortable.options(oldParentNode).onChange(element);
810
- droponOptions.onChange(element);
811
- }
812
- },
813
-
814
- unmark: function() {
815
- if(Sortable._marker) Sortable._marker.hide();
816
- },
817
-
818
- mark: function(dropon, position) {
819
- // mark on ghosting only
820
- var sortable = Sortable.options(dropon.parentNode);
821
- if(sortable && !sortable.ghosting) return;
822
-
823
- if(!Sortable._marker) {
824
- Sortable._marker =
825
- ($('dropmarker') || Element.extend(document.createElement('DIV'))).
826
- hide().addClassName('dropmarker').setStyle({position:'absolute'});
827
- document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
828
- }
829
- var offsets = dropon.cumulativeOffset();
830
- Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
831
-
832
- if(position=='after')
833
- if(sortable.overlap == 'horizontal')
834
- Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
835
- else
836
- Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
837
-
838
- Sortable._marker.show();
839
- },
840
-
841
- _tree: function(element, options, parent) {
842
- var children = Sortable.findElements(element, options) || [];
843
-
844
- for (var i = 0; i < children.length; ++i) {
845
- var match = children[i].id.match(options.format);
846
-
847
- if (!match) continue;
848
-
849
- var child = {
850
- id: encodeURIComponent(match ? match[1] : null),
851
- element: element,
852
- parent: parent,
853
- children: [],
854
- position: parent.children.length,
855
- container: $(children[i]).down(options.treeTag)
856
- };
857
-
858
- /* Get the element containing the children and recurse over it */
859
- if (child.container)
860
- this._tree(child.container, options, child);
861
-
862
- parent.children.push (child);
863
- }
864
-
865
- return parent;
866
- },
867
-
868
- tree: function(element) {
869
- element = $(element);
870
- var sortableOptions = this.options(element);
871
- var options = Object.extend({
872
- tag: sortableOptions.tag,
873
- treeTag: sortableOptions.treeTag,
874
- only: sortableOptions.only,
875
- name: element.id,
876
- format: sortableOptions.format
877
- }, arguments[1] || { });
878
-
879
- var root = {
880
- id: null,
881
- parent: null,
882
- children: [],
883
- container: element,
884
- position: 0
885
- };
886
-
887
- return Sortable._tree(element, options, root);
888
- },
889
-
890
- /* Construct a [i] index for a particular node */
891
- _constructIndex: function(node) {
892
- var index = '';
893
- do {
894
- if (node.id) index = '[' + node.position + ']' + index;
895
- } while ((node = node.parent) != null);
896
- return index;
897
- },
898
-
899
- sequence: function(element) {
900
- element = $(element);
901
- var options = Object.extend(this.options(element), arguments[1] || { });
902
-
903
- return $(this.findElements(element, options) || []).map( function(item) {
904
- return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
905
- });
906
- },
907
-
908
- setSequence: function(element, new_sequence) {
909
- element = $(element);
910
- var options = Object.extend(this.options(element), arguments[2] || { });
911
-
912
- var nodeMap = { };
913
- this.findElements(element, options).each( function(n) {
914
- if (n.id.match(options.format))
915
- nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
916
- n.parentNode.removeChild(n);
917
- });
918
-
919
- new_sequence.each(function(ident) {
920
- var n = nodeMap[ident];
921
- if (n) {
922
- n[1].appendChild(n[0]);
923
- delete nodeMap[ident];
924
- }
925
- });
926
- },
927
-
928
- serialize: function(element) {
929
- element = $(element);
930
- var options = Object.extend(Sortable.options(element), arguments[1] || { });
931
- var name = encodeURIComponent(
932
- (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
933
-
934
- if (options.tree) {
935
- return Sortable.tree(element, arguments[1]).children.map( function (item) {
936
- return [name + Sortable._constructIndex(item) + "[id]=" +
937
- encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
938
- }).flatten().join('&');
939
- } else {
940
- return Sortable.sequence(element, arguments[1]).map( function(item) {
941
- return name + "[]=" + encodeURIComponent(item);
942
- }).join('&');
943
- }
944
- }
945
- };
946
-
947
- // Returns true if child is contained within element
948
- Element.isParent = function(child, element) {
949
- if (!child.parentNode || child == element) return false;
950
- if (child.parentNode == element) return true;
951
- return Element.isParent(child.parentNode, element);
952
- };
953
-
954
- Element.findChildren = function(element, only, recursive, tagName) {
955
- if(!element.hasChildNodes()) return null;
956
- tagName = tagName.toUpperCase();
957
- if(only) only = [only].flatten();
958
- var elements = [];
959
- $A(element.childNodes).each( function(e) {
960
- if(e.tagName && e.tagName.toUpperCase()==tagName &&
961
- (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
962
- elements.push(e);
963
- if(recursive) {
964
- var grandchildren = Element.findChildren(e, only, recursive, tagName);
965
- if(grandchildren) elements.push(grandchildren);
966
- }
967
- });
968
-
969
- return (elements.length>0 ? elements.flatten() : []);
970
- };
971
-
972
- Element.offsetSize = function (element, type) {
973
- return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
974
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/effects.js DELETED
@@ -1,1123 +0,0 @@
1
- // script.aculo.us effects.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- // Contributors:
5
- // Justin Palmer (http://encytemedia.com/)
6
- // Mark Pilgrim (http://diveintomark.org/)
7
- // Martin Bialasinki
8
- //
9
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
10
- // For details, see the script.aculo.us web site: http://script.aculo.us/
11
-
12
- // converts rgb() and #xxx to #xxxxxx format,
13
- // returns self (or first argument) if not convertable
14
- String.prototype.parseColor = function() {
15
- var color = '#';
16
- if (this.slice(0,4) == 'rgb(') {
17
- var cols = this.slice(4,this.length-1).split(',');
18
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
19
- } else {
20
- if (this.slice(0,1) == '#') {
21
- if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
22
- if (this.length==7) color = this.toLowerCase();
23
- }
24
- }
25
- return (color.length==7 ? color : (arguments[0] || this));
26
- };
27
-
28
- /*--------------------------------------------------------------------------*/
29
-
30
- Element.collectTextNodes = function(element) {
31
- return $A($(element).childNodes).collect( function(node) {
32
- return (node.nodeType==3 ? node.nodeValue :
33
- (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
34
- }).flatten().join('');
35
- };
36
-
37
- Element.collectTextNodesIgnoreClass = function(element, className) {
38
- return $A($(element).childNodes).collect( function(node) {
39
- return (node.nodeType==3 ? node.nodeValue :
40
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
41
- Element.collectTextNodesIgnoreClass(node, className) : ''));
42
- }).flatten().join('');
43
- };
44
-
45
- Element.setContentZoom = function(element, percent) {
46
- element = $(element);
47
- element.setStyle({fontSize: (percent/100) + 'em'});
48
- if (Prototype.Browser.WebKit) window.scrollBy(0,0);
49
- return element;
50
- };
51
-
52
- Element.getInlineOpacity = function(element){
53
- return $(element).style.opacity || '';
54
- };
55
-
56
- Element.forceRerendering = function(element) {
57
- try {
58
- element = $(element);
59
- var n = document.createTextNode(' ');
60
- element.appendChild(n);
61
- element.removeChild(n);
62
- } catch(e) { }
63
- };
64
-
65
- /*--------------------------------------------------------------------------*/
66
-
67
- var Effect = {
68
- _elementDoesNotExistError: {
69
- name: 'ElementDoesNotExistError',
70
- message: 'The specified DOM element does not exist, but is required for this effect to operate'
71
- },
72
- Transitions: {
73
- linear: Prototype.K,
74
- sinoidal: function(pos) {
75
- return (-Math.cos(pos*Math.PI)/2) + .5;
76
- },
77
- reverse: function(pos) {
78
- return 1-pos;
79
- },
80
- flicker: function(pos) {
81
- var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
82
- return pos > 1 ? 1 : pos;
83
- },
84
- wobble: function(pos) {
85
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
86
- },
87
- pulse: function(pos, pulses) {
88
- return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
89
- },
90
- spring: function(pos) {
91
- return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
92
- },
93
- none: function(pos) {
94
- return 0;
95
- },
96
- full: function(pos) {
97
- return 1;
98
- }
99
- },
100
- DefaultOptions: {
101
- duration: 1.0, // seconds
102
- fps: 100, // 100= assume 66fps max.
103
- sync: false, // true for combining
104
- from: 0.0,
105
- to: 1.0,
106
- delay: 0.0,
107
- queue: 'parallel'
108
- },
109
- tagifyText: function(element) {
110
- var tagifyStyle = 'position:relative';
111
- if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
112
-
113
- element = $(element);
114
- $A(element.childNodes).each( function(child) {
115
- if (child.nodeType==3) {
116
- child.nodeValue.toArray().each( function(character) {
117
- element.insertBefore(
118
- new Element('span', {style: tagifyStyle}).update(
119
- character == ' ' ? String.fromCharCode(160) : character),
120
- child);
121
- });
122
- Element.remove(child);
123
- }
124
- });
125
- },
126
- multiple: function(element, effect) {
127
- var elements;
128
- if (((typeof element == 'object') ||
129
- Object.isFunction(element)) &&
130
- (element.length))
131
- elements = element;
132
- else
133
- elements = $(element).childNodes;
134
-
135
- var options = Object.extend({
136
- speed: 0.1,
137
- delay: 0.0
138
- }, arguments[2] || { });
139
- var masterDelay = options.delay;
140
-
141
- $A(elements).each( function(element, index) {
142
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
143
- });
144
- },
145
- PAIRS: {
146
- 'slide': ['SlideDown','SlideUp'],
147
- 'blind': ['BlindDown','BlindUp'],
148
- 'appear': ['Appear','Fade']
149
- },
150
- toggle: function(element, effect, options) {
151
- element = $(element);
152
- effect = (effect || 'appear').toLowerCase();
153
-
154
- return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
155
- queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
156
- }, options || {}));
157
- }
158
- };
159
-
160
- Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
161
-
162
- /* ------------- core effects ------------- */
163
-
164
- Effect.ScopedQueue = Class.create(Enumerable, {
165
- initialize: function() {
166
- this.effects = [];
167
- this.interval = null;
168
- },
169
- _each: function(iterator) {
170
- this.effects._each(iterator);
171
- },
172
- add: function(effect) {
173
- var timestamp = new Date().getTime();
174
-
175
- var position = Object.isString(effect.options.queue) ?
176
- effect.options.queue : effect.options.queue.position;
177
-
178
- switch(position) {
179
- case 'front':
180
- // move unstarted effects after this effect
181
- this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
182
- e.startOn += effect.finishOn;
183
- e.finishOn += effect.finishOn;
184
- });
185
- break;
186
- case 'with-last':
187
- timestamp = this.effects.pluck('startOn').max() || timestamp;
188
- break;
189
- case 'end':
190
- // start effect after last queued effect has finished
191
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
192
- break;
193
- }
194
-
195
- effect.startOn += timestamp;
196
- effect.finishOn += timestamp;
197
-
198
- if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
199
- this.effects.push(effect);
200
-
201
- if (!this.interval)
202
- this.interval = setInterval(this.loop.bind(this), 15);
203
- },
204
- remove: function(effect) {
205
- this.effects = this.effects.reject(function(e) { return e==effect });
206
- if (this.effects.length == 0) {
207
- clearInterval(this.interval);
208
- this.interval = null;
209
- }
210
- },
211
- loop: function() {
212
- var timePos = new Date().getTime();
213
- for(var i=0, len=this.effects.length;i<len;i++)
214
- this.effects[i] && this.effects[i].loop(timePos);
215
- }
216
- });
217
-
218
- Effect.Queues = {
219
- instances: $H(),
220
- get: function(queueName) {
221
- if (!Object.isString(queueName)) return queueName;
222
-
223
- return this.instances.get(queueName) ||
224
- this.instances.set(queueName, new Effect.ScopedQueue());
225
- }
226
- };
227
- Effect.Queue = Effect.Queues.get('global');
228
-
229
- Effect.Base = Class.create({
230
- position: null,
231
- start: function(options) {
232
- if (options && options.transition === false) options.transition = Effect.Transitions.linear;
233
- this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
234
- this.currentFrame = 0;
235
- this.state = 'idle';
236
- this.startOn = this.options.delay*1000;
237
- this.finishOn = this.startOn+(this.options.duration*1000);
238
- this.fromToDelta = this.options.to-this.options.from;
239
- this.totalTime = this.finishOn-this.startOn;
240
- this.totalFrames = this.options.fps*this.options.duration;
241
-
242
- this.render = (function() {
243
- function dispatch(effect, eventName) {
244
- if (effect.options[eventName + 'Internal'])
245
- effect.options[eventName + 'Internal'](effect);
246
- if (effect.options[eventName])
247
- effect.options[eventName](effect);
248
- }
249
-
250
- return function(pos) {
251
- if (this.state === "idle") {
252
- this.state = "running";
253
- dispatch(this, 'beforeSetup');
254
- if (this.setup) this.setup();
255
- dispatch(this, 'afterSetup');
256
- }
257
- if (this.state === "running") {
258
- pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
259
- this.position = pos;
260
- dispatch(this, 'beforeUpdate');
261
- if (this.update) this.update(pos);
262
- dispatch(this, 'afterUpdate');
263
- }
264
- };
265
- })();
266
-
267
- this.event('beforeStart');
268
- if (!this.options.sync)
269
- Effect.Queues.get(Object.isString(this.options.queue) ?
270
- 'global' : this.options.queue.scope).add(this);
271
- },
272
- loop: function(timePos) {
273
- if (timePos >= this.startOn) {
274
- if (timePos >= this.finishOn) {
275
- this.render(1.0);
276
- this.cancel();
277
- this.event('beforeFinish');
278
- if (this.finish) this.finish();
279
- this.event('afterFinish');
280
- return;
281
- }
282
- var pos = (timePos - this.startOn) / this.totalTime,
283
- frame = (pos * this.totalFrames).round();
284
- if (frame > this.currentFrame) {
285
- this.render(pos);
286
- this.currentFrame = frame;
287
- }
288
- }
289
- },
290
- cancel: function() {
291
- if (!this.options.sync)
292
- Effect.Queues.get(Object.isString(this.options.queue) ?
293
- 'global' : this.options.queue.scope).remove(this);
294
- this.state = 'finished';
295
- },
296
- event: function(eventName) {
297
- if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
298
- if (this.options[eventName]) this.options[eventName](this);
299
- },
300
- inspect: function() {
301
- var data = $H();
302
- for(property in this)
303
- if (!Object.isFunction(this[property])) data.set(property, this[property]);
304
- return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
305
- }
306
- });
307
-
308
- Effect.Parallel = Class.create(Effect.Base, {
309
- initialize: function(effects) {
310
- this.effects = effects || [];
311
- this.start(arguments[1]);
312
- },
313
- update: function(position) {
314
- this.effects.invoke('render', position);
315
- },
316
- finish: function(position) {
317
- this.effects.each( function(effect) {
318
- effect.render(1.0);
319
- effect.cancel();
320
- effect.event('beforeFinish');
321
- if (effect.finish) effect.finish(position);
322
- effect.event('afterFinish');
323
- });
324
- }
325
- });
326
-
327
- Effect.Tween = Class.create(Effect.Base, {
328
- initialize: function(object, from, to) {
329
- object = Object.isString(object) ? $(object) : object;
330
- var args = $A(arguments), method = args.last(),
331
- options = args.length == 5 ? args[3] : null;
332
- this.method = Object.isFunction(method) ? method.bind(object) :
333
- Object.isFunction(object[method]) ? object[method].bind(object) :
334
- function(value) { object[method] = value };
335
- this.start(Object.extend({ from: from, to: to }, options || { }));
336
- },
337
- update: function(position) {
338
- this.method(position);
339
- }
340
- });
341
-
342
- Effect.Event = Class.create(Effect.Base, {
343
- initialize: function() {
344
- this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
345
- },
346
- update: Prototype.emptyFunction
347
- });
348
-
349
- Effect.Opacity = Class.create(Effect.Base, {
350
- initialize: function(element) {
351
- this.element = $(element);
352
- if (!this.element) throw(Effect._elementDoesNotExistError);
353
- // make this work on IE on elements without 'layout'
354
- if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
355
- this.element.setStyle({zoom: 1});
356
- var options = Object.extend({
357
- from: this.element.getOpacity() || 0.0,
358
- to: 1.0
359
- }, arguments[1] || { });
360
- this.start(options);
361
- },
362
- update: function(position) {
363
- this.element.setOpacity(position);
364
- }
365
- });
366
-
367
- Effect.Move = Class.create(Effect.Base, {
368
- initialize: function(element) {
369
- this.element = $(element);
370
- if (!this.element) throw(Effect._elementDoesNotExistError);
371
- var options = Object.extend({
372
- x: 0,
373
- y: 0,
374
- mode: 'relative'
375
- }, arguments[1] || { });
376
- this.start(options);
377
- },
378
- setup: function() {
379
- this.element.makePositioned();
380
- this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
381
- this.originalTop = parseFloat(this.element.getStyle('top') || '0');
382
- if (this.options.mode == 'absolute') {
383
- this.options.x = this.options.x - this.originalLeft;
384
- this.options.y = this.options.y - this.originalTop;
385
- }
386
- },
387
- update: function(position) {
388
- this.element.setStyle({
389
- left: (this.options.x * position + this.originalLeft).round() + 'px',
390
- top: (this.options.y * position + this.originalTop).round() + 'px'
391
- });
392
- }
393
- });
394
-
395
- // for backwards compatibility
396
- Effect.MoveBy = function(element, toTop, toLeft) {
397
- return new Effect.Move(element,
398
- Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
399
- };
400
-
401
- Effect.Scale = Class.create(Effect.Base, {
402
- initialize: function(element, percent) {
403
- this.element = $(element);
404
- if (!this.element) throw(Effect._elementDoesNotExistError);
405
- var options = Object.extend({
406
- scaleX: true,
407
- scaleY: true,
408
- scaleContent: true,
409
- scaleFromCenter: false,
410
- scaleMode: 'box', // 'box' or 'contents' or { } with provided values
411
- scaleFrom: 100.0,
412
- scaleTo: percent
413
- }, arguments[2] || { });
414
- this.start(options);
415
- },
416
- setup: function() {
417
- this.restoreAfterFinish = this.options.restoreAfterFinish || false;
418
- this.elementPositioning = this.element.getStyle('position');
419
-
420
- this.originalStyle = { };
421
- ['top','left','width','height','fontSize'].each( function(k) {
422
- this.originalStyle[k] = this.element.style[k];
423
- }.bind(this));
424
-
425
- this.originalTop = this.element.offsetTop;
426
- this.originalLeft = this.element.offsetLeft;
427
-
428
- var fontSize = this.element.getStyle('font-size') || '100%';
429
- ['em','px','%','pt'].each( function(fontSizeType) {
430
- if (fontSize.indexOf(fontSizeType)>0) {
431
- this.fontSize = parseFloat(fontSize);
432
- this.fontSizeType = fontSizeType;
433
- }
434
- }.bind(this));
435
-
436
- this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
437
-
438
- this.dims = null;
439
- if (this.options.scaleMode=='box')
440
- this.dims = [this.element.offsetHeight, this.element.offsetWidth];
441
- if (/^content/.test(this.options.scaleMode))
442
- this.dims = [this.element.scrollHeight, this.element.scrollWidth];
443
- if (!this.dims)
444
- this.dims = [this.options.scaleMode.originalHeight,
445
- this.options.scaleMode.originalWidth];
446
- },
447
- update: function(position) {
448
- var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
449
- if (this.options.scaleContent && this.fontSize)
450
- this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
451
- this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
452
- },
453
- finish: function(position) {
454
- if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
455
- },
456
- setDimensions: function(height, width) {
457
- var d = { };
458
- if (this.options.scaleX) d.width = width.round() + 'px';
459
- if (this.options.scaleY) d.height = height.round() + 'px';
460
- if (this.options.scaleFromCenter) {
461
- var topd = (height - this.dims[0])/2;
462
- var leftd = (width - this.dims[1])/2;
463
- if (this.elementPositioning == 'absolute') {
464
- if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
465
- if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
466
- } else {
467
- if (this.options.scaleY) d.top = -topd + 'px';
468
- if (this.options.scaleX) d.left = -leftd + 'px';
469
- }
470
- }
471
- this.element.setStyle(d);
472
- }
473
- });
474
-
475
- Effect.Highlight = Class.create(Effect.Base, {
476
- initialize: function(element) {
477
- this.element = $(element);
478
- if (!this.element) throw(Effect._elementDoesNotExistError);
479
- var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
480
- this.start(options);
481
- },
482
- setup: function() {
483
- // Prevent executing on elements not in the layout flow
484
- if (this.element.getStyle('display')=='none') { this.cancel(); return; }
485
- // Disable background image during the effect
486
- this.oldStyle = { };
487
- if (!this.options.keepBackgroundImage) {
488
- this.oldStyle.backgroundImage = this.element.getStyle('background-image');
489
- this.element.setStyle({backgroundImage: 'none'});
490
- }
491
- if (!this.options.endcolor)
492
- this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
493
- if (!this.options.restorecolor)
494
- this.options.restorecolor = this.element.getStyle('background-color');
495
- // init color calculations
496
- this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
497
- this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
498
- },
499
- update: function(position) {
500
- this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
501
- return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
502
- },
503
- finish: function() {
504
- this.element.setStyle(Object.extend(this.oldStyle, {
505
- backgroundColor: this.options.restorecolor
506
- }));
507
- }
508
- });
509
-
510
- Effect.ScrollTo = function(element) {
511
- var options = arguments[1] || { },
512
- scrollOffsets = document.viewport.getScrollOffsets(),
513
- elementOffsets = $(element).cumulativeOffset();
514
-
515
- if (options.offset) elementOffsets[1] += options.offset;
516
-
517
- return new Effect.Tween(null,
518
- scrollOffsets.top,
519
- elementOffsets[1],
520
- options,
521
- function(p){ scrollTo(scrollOffsets.left, p.round()); }
522
- );
523
- };
524
-
525
- /* ------------- combination effects ------------- */
526
-
527
- Effect.Fade = function(element) {
528
- element = $(element);
529
- var oldOpacity = element.getInlineOpacity();
530
- var options = Object.extend({
531
- from: element.getOpacity() || 1.0,
532
- to: 0.0,
533
- afterFinishInternal: function(effect) {
534
- if (effect.options.to!=0) return;
535
- effect.element.hide().setStyle({opacity: oldOpacity});
536
- }
537
- }, arguments[1] || { });
538
- return new Effect.Opacity(element,options);
539
- };
540
-
541
- Effect.Appear = function(element) {
542
- element = $(element);
543
- var options = Object.extend({
544
- from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
545
- to: 1.0,
546
- // force Safari to render floated elements properly
547
- afterFinishInternal: function(effect) {
548
- effect.element.forceRerendering();
549
- },
550
- beforeSetup: function(effect) {
551
- effect.element.setOpacity(effect.options.from).show();
552
- }}, arguments[1] || { });
553
- return new Effect.Opacity(element,options);
554
- };
555
-
556
- Effect.Puff = function(element) {
557
- element = $(element);
558
- var oldStyle = {
559
- opacity: element.getInlineOpacity(),
560
- position: element.getStyle('position'),
561
- top: element.style.top,
562
- left: element.style.left,
563
- width: element.style.width,
564
- height: element.style.height
565
- };
566
- return new Effect.Parallel(
567
- [ new Effect.Scale(element, 200,
568
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
569
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
570
- Object.extend({ duration: 1.0,
571
- beforeSetupInternal: function(effect) {
572
- Position.absolutize(effect.effects[0].element);
573
- },
574
- afterFinishInternal: function(effect) {
575
- effect.effects[0].element.hide().setStyle(oldStyle); }
576
- }, arguments[1] || { })
577
- );
578
- };
579
-
580
- Effect.BlindUp = function(element) {
581
- element = $(element);
582
- element.makeClipping();
583
- return new Effect.Scale(element, 0,
584
- Object.extend({ scaleContent: false,
585
- scaleX: false,
586
- restoreAfterFinish: true,
587
- afterFinishInternal: function(effect) {
588
- effect.element.hide().undoClipping();
589
- }
590
- }, arguments[1] || { })
591
- );
592
- };
593
-
594
- Effect.BlindDown = function(element) {
595
- element = $(element);
596
- var elementDimensions = element.getDimensions();
597
- return new Effect.Scale(element, 100, Object.extend({
598
- scaleContent: false,
599
- scaleX: false,
600
- scaleFrom: 0,
601
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
602
- restoreAfterFinish: true,
603
- afterSetup: function(effect) {
604
- effect.element.makeClipping().setStyle({height: '0px'}).show();
605
- },
606
- afterFinishInternal: function(effect) {
607
- effect.element.undoClipping();
608
- }
609
- }, arguments[1] || { }));
610
- };
611
-
612
- Effect.SwitchOff = function(element) {
613
- element = $(element);
614
- var oldOpacity = element.getInlineOpacity();
615
- return new Effect.Appear(element, Object.extend({
616
- duration: 0.4,
617
- from: 0,
618
- transition: Effect.Transitions.flicker,
619
- afterFinishInternal: function(effect) {
620
- new Effect.Scale(effect.element, 1, {
621
- duration: 0.3, scaleFromCenter: true,
622
- scaleX: false, scaleContent: false, restoreAfterFinish: true,
623
- beforeSetup: function(effect) {
624
- effect.element.makePositioned().makeClipping();
625
- },
626
- afterFinishInternal: function(effect) {
627
- effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
628
- }
629
- });
630
- }
631
- }, arguments[1] || { }));
632
- };
633
-
634
- Effect.DropOut = function(element) {
635
- element = $(element);
636
- var oldStyle = {
637
- top: element.getStyle('top'),
638
- left: element.getStyle('left'),
639
- opacity: element.getInlineOpacity() };
640
- return new Effect.Parallel(
641
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
642
- new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
643
- Object.extend(
644
- { duration: 0.5,
645
- beforeSetup: function(effect) {
646
- effect.effects[0].element.makePositioned();
647
- },
648
- afterFinishInternal: function(effect) {
649
- effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
650
- }
651
- }, arguments[1] || { }));
652
- };
653
-
654
- Effect.Shake = function(element) {
655
- element = $(element);
656
- var options = Object.extend({
657
- distance: 20,
658
- duration: 0.5
659
- }, arguments[1] || {});
660
- var distance = parseFloat(options.distance);
661
- var split = parseFloat(options.duration) / 10.0;
662
- var oldStyle = {
663
- top: element.getStyle('top'),
664
- left: element.getStyle('left') };
665
- return new Effect.Move(element,
666
- { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
667
- new Effect.Move(effect.element,
668
- { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
669
- new Effect.Move(effect.element,
670
- { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
671
- new Effect.Move(effect.element,
672
- { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
673
- new Effect.Move(effect.element,
674
- { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
675
- new Effect.Move(effect.element,
676
- { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
677
- effect.element.undoPositioned().setStyle(oldStyle);
678
- }}); }}); }}); }}); }}); }});
679
- };
680
-
681
- Effect.SlideDown = function(element) {
682
- element = $(element).cleanWhitespace();
683
- // SlideDown need to have the content of the element wrapped in a container element with fixed height!
684
- var oldInnerBottom = element.down().getStyle('bottom');
685
- var elementDimensions = element.getDimensions();
686
- return new Effect.Scale(element, 100, Object.extend({
687
- scaleContent: false,
688
- scaleX: false,
689
- scaleFrom: window.opera ? 0 : 1,
690
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
691
- restoreAfterFinish: true,
692
- afterSetup: function(effect) {
693
- effect.element.makePositioned();
694
- effect.element.down().makePositioned();
695
- if (window.opera) effect.element.setStyle({top: ''});
696
- effect.element.makeClipping().setStyle({height: '0px'}).show();
697
- },
698
- afterUpdateInternal: function(effect) {
699
- effect.element.down().setStyle({bottom:
700
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
701
- },
702
- afterFinishInternal: function(effect) {
703
- effect.element.undoClipping().undoPositioned();
704
- effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
705
- }, arguments[1] || { })
706
- );
707
- };
708
-
709
- Effect.SlideUp = function(element) {
710
- element = $(element).cleanWhitespace();
711
- var oldInnerBottom = element.down().getStyle('bottom');
712
- var elementDimensions = element.getDimensions();
713
- return new Effect.Scale(element, window.opera ? 0 : 1,
714
- Object.extend({ scaleContent: false,
715
- scaleX: false,
716
- scaleMode: 'box',
717
- scaleFrom: 100,
718
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
719
- restoreAfterFinish: true,
720
- afterSetup: function(effect) {
721
- effect.element.makePositioned();
722
- effect.element.down().makePositioned();
723
- if (window.opera) effect.element.setStyle({top: ''});
724
- effect.element.makeClipping().show();
725
- },
726
- afterUpdateInternal: function(effect) {
727
- effect.element.down().setStyle({bottom:
728
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
729
- },
730
- afterFinishInternal: function(effect) {
731
- effect.element.hide().undoClipping().undoPositioned();
732
- effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
733
- }
734
- }, arguments[1] || { })
735
- );
736
- };
737
-
738
- // Bug in opera makes the TD containing this element expand for a instance after finish
739
- Effect.Squish = function(element) {
740
- return new Effect.Scale(element, window.opera ? 1 : 0, {
741
- restoreAfterFinish: true,
742
- beforeSetup: function(effect) {
743
- effect.element.makeClipping();
744
- },
745
- afterFinishInternal: function(effect) {
746
- effect.element.hide().undoClipping();
747
- }
748
- });
749
- };
750
-
751
- Effect.Grow = function(element) {
752
- element = $(element);
753
- var options = Object.extend({
754
- direction: 'center',
755
- moveTransition: Effect.Transitions.sinoidal,
756
- scaleTransition: Effect.Transitions.sinoidal,
757
- opacityTransition: Effect.Transitions.full
758
- }, arguments[1] || { });
759
- var oldStyle = {
760
- top: element.style.top,
761
- left: element.style.left,
762
- height: element.style.height,
763
- width: element.style.width,
764
- opacity: element.getInlineOpacity() };
765
-
766
- var dims = element.getDimensions();
767
- var initialMoveX, initialMoveY;
768
- var moveX, moveY;
769
-
770
- switch (options.direction) {
771
- case 'top-left':
772
- initialMoveX = initialMoveY = moveX = moveY = 0;
773
- break;
774
- case 'top-right':
775
- initialMoveX = dims.width;
776
- initialMoveY = moveY = 0;
777
- moveX = -dims.width;
778
- break;
779
- case 'bottom-left':
780
- initialMoveX = moveX = 0;
781
- initialMoveY = dims.height;
782
- moveY = -dims.height;
783
- break;
784
- case 'bottom-right':
785
- initialMoveX = dims.width;
786
- initialMoveY = dims.height;
787
- moveX = -dims.width;
788
- moveY = -dims.height;
789
- break;
790
- case 'center':
791
- initialMoveX = dims.width / 2;
792
- initialMoveY = dims.height / 2;
793
- moveX = -dims.width / 2;
794
- moveY = -dims.height / 2;
795
- break;
796
- }
797
-
798
- return new Effect.Move(element, {
799
- x: initialMoveX,
800
- y: initialMoveY,
801
- duration: 0.01,
802
- beforeSetup: function(effect) {
803
- effect.element.hide().makeClipping().makePositioned();
804
- },
805
- afterFinishInternal: function(effect) {
806
- new Effect.Parallel(
807
- [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
808
- new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
809
- new Effect.Scale(effect.element, 100, {
810
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
811
- sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
812
- ], Object.extend({
813
- beforeSetup: function(effect) {
814
- effect.effects[0].element.setStyle({height: '0px'}).show();
815
- },
816
- afterFinishInternal: function(effect) {
817
- effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
818
- }
819
- }, options)
820
- );
821
- }
822
- });
823
- };
824
-
825
- Effect.Shrink = function(element) {
826
- element = $(element);
827
- var options = Object.extend({
828
- direction: 'center',
829
- moveTransition: Effect.Transitions.sinoidal,
830
- scaleTransition: Effect.Transitions.sinoidal,
831
- opacityTransition: Effect.Transitions.none
832
- }, arguments[1] || { });
833
- var oldStyle = {
834
- top: element.style.top,
835
- left: element.style.left,
836
- height: element.style.height,
837
- width: element.style.width,
838
- opacity: element.getInlineOpacity() };
839
-
840
- var dims = element.getDimensions();
841
- var moveX, moveY;
842
-
843
- switch (options.direction) {
844
- case 'top-left':
845
- moveX = moveY = 0;
846
- break;
847
- case 'top-right':
848
- moveX = dims.width;
849
- moveY = 0;
850
- break;
851
- case 'bottom-left':
852
- moveX = 0;
853
- moveY = dims.height;
854
- break;
855
- case 'bottom-right':
856
- moveX = dims.width;
857
- moveY = dims.height;
858
- break;
859
- case 'center':
860
- moveX = dims.width / 2;
861
- moveY = dims.height / 2;
862
- break;
863
- }
864
-
865
- return new Effect.Parallel(
866
- [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
867
- new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
868
- new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
869
- ], Object.extend({
870
- beforeStartInternal: function(effect) {
871
- effect.effects[0].element.makePositioned().makeClipping();
872
- },
873
- afterFinishInternal: function(effect) {
874
- effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
875
- }, options)
876
- );
877
- };
878
-
879
- Effect.Pulsate = function(element) {
880
- element = $(element);
881
- var options = arguments[1] || { },
882
- oldOpacity = element.getInlineOpacity(),
883
- transition = options.transition || Effect.Transitions.linear,
884
- reverser = function(pos){
885
- return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
886
- };
887
-
888
- return new Effect.Opacity(element,
889
- Object.extend(Object.extend({ duration: 2.0, from: 0,
890
- afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
891
- }, options), {transition: reverser}));
892
- };
893
-
894
- Effect.Fold = function(element) {
895
- element = $(element);
896
- var oldStyle = {
897
- top: element.style.top,
898
- left: element.style.left,
899
- width: element.style.width,
900
- height: element.style.height };
901
- element.makeClipping();
902
- return new Effect.Scale(element, 5, Object.extend({
903
- scaleContent: false,
904
- scaleX: false,
905
- afterFinishInternal: function(effect) {
906
- new Effect.Scale(element, 1, {
907
- scaleContent: false,
908
- scaleY: false,
909
- afterFinishInternal: function(effect) {
910
- effect.element.hide().undoClipping().setStyle(oldStyle);
911
- } });
912
- }}, arguments[1] || { }));
913
- };
914
-
915
- Effect.Morph = Class.create(Effect.Base, {
916
- initialize: function(element) {
917
- this.element = $(element);
918
- if (!this.element) throw(Effect._elementDoesNotExistError);
919
- var options = Object.extend({
920
- style: { }
921
- }, arguments[1] || { });
922
-
923
- if (!Object.isString(options.style)) this.style = $H(options.style);
924
- else {
925
- if (options.style.include(':'))
926
- this.style = options.style.parseStyle();
927
- else {
928
- this.element.addClassName(options.style);
929
- this.style = $H(this.element.getStyles());
930
- this.element.removeClassName(options.style);
931
- var css = this.element.getStyles();
932
- this.style = this.style.reject(function(style) {
933
- return style.value == css[style.key];
934
- });
935
- options.afterFinishInternal = function(effect) {
936
- effect.element.addClassName(effect.options.style);
937
- effect.transforms.each(function(transform) {
938
- effect.element.style[transform.style] = '';
939
- });
940
- };
941
- }
942
- }
943
- this.start(options);
944
- },
945
-
946
- setup: function(){
947
- function parseColor(color){
948
- if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
949
- color = color.parseColor();
950
- return $R(0,2).map(function(i){
951
- return parseInt( color.slice(i*2+1,i*2+3), 16 );
952
- });
953
- }
954
- this.transforms = this.style.map(function(pair){
955
- var property = pair[0], value = pair[1], unit = null;
956
-
957
- if (value.parseColor('#zzzzzz') != '#zzzzzz') {
958
- value = value.parseColor();
959
- unit = 'color';
960
- } else if (property == 'opacity') {
961
- value = parseFloat(value);
962
- if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
963
- this.element.setStyle({zoom: 1});
964
- } else if (Element.CSS_LENGTH.test(value)) {
965
- var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
966
- value = parseFloat(components[1]);
967
- unit = (components.length == 3) ? components[2] : null;
968
- }
969
-
970
- var originalValue = this.element.getStyle(property);
971
- return {
972
- style: property.camelize(),
973
- originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
974
- targetValue: unit=='color' ? parseColor(value) : value,
975
- unit: unit
976
- };
977
- }.bind(this)).reject(function(transform){
978
- return (
979
- (transform.originalValue == transform.targetValue) ||
980
- (
981
- transform.unit != 'color' &&
982
- (isNaN(transform.originalValue) || isNaN(transform.targetValue))
983
- )
984
- );
985
- });
986
- },
987
- update: function(position) {
988
- var style = { }, transform, i = this.transforms.length;
989
- while(i--)
990
- style[(transform = this.transforms[i]).style] =
991
- transform.unit=='color' ? '#'+
992
- (Math.round(transform.originalValue[0]+
993
- (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
994
- (Math.round(transform.originalValue[1]+
995
- (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
996
- (Math.round(transform.originalValue[2]+
997
- (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
998
- (transform.originalValue +
999
- (transform.targetValue - transform.originalValue) * position).toFixed(3) +
1000
- (transform.unit === null ? '' : transform.unit);
1001
- this.element.setStyle(style, true);
1002
- }
1003
- });
1004
-
1005
- Effect.Transform = Class.create({
1006
- initialize: function(tracks){
1007
- this.tracks = [];
1008
- this.options = arguments[1] || { };
1009
- this.addTracks(tracks);
1010
- },
1011
- addTracks: function(tracks){
1012
- tracks.each(function(track){
1013
- track = $H(track);
1014
- var data = track.values().first();
1015
- this.tracks.push($H({
1016
- ids: track.keys().first(),
1017
- effect: Effect.Morph,
1018
- options: { style: data }
1019
- }));
1020
- }.bind(this));
1021
- return this;
1022
- },
1023
- play: function(){
1024
- return new Effect.Parallel(
1025
- this.tracks.map(function(track){
1026
- var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
1027
- var elements = [$(ids) || $$(ids)].flatten();
1028
- return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
1029
- }).flatten(),
1030
- this.options
1031
- );
1032
- }
1033
- });
1034
-
1035
- Element.CSS_PROPERTIES = $w(
1036
- 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
1037
- 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
1038
- 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
1039
- 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
1040
- 'fontSize fontWeight height left letterSpacing lineHeight ' +
1041
- 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
1042
- 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
1043
- 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
1044
- 'right textIndent top width wordSpacing zIndex');
1045
-
1046
- Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
1047
-
1048
- String.__parseStyleElement = document.createElement('div');
1049
- String.prototype.parseStyle = function(){
1050
- var style, styleRules = $H();
1051
- if (Prototype.Browser.WebKit)
1052
- style = new Element('div',{style:this}).style;
1053
- else {
1054
- String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
1055
- style = String.__parseStyleElement.childNodes[0].style;
1056
- }
1057
-
1058
- Element.CSS_PROPERTIES.each(function(property){
1059
- if (style[property]) styleRules.set(property, style[property]);
1060
- });
1061
-
1062
- if (Prototype.Browser.IE && this.include('opacity'))
1063
- styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
1064
-
1065
- return styleRules;
1066
- };
1067
-
1068
- if (document.defaultView && document.defaultView.getComputedStyle) {
1069
- Element.getStyles = function(element) {
1070
- var css = document.defaultView.getComputedStyle($(element), null);
1071
- return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
1072
- styles[property] = css[property];
1073
- return styles;
1074
- });
1075
- };
1076
- } else {
1077
- Element.getStyles = function(element) {
1078
- element = $(element);
1079
- var css = element.currentStyle, styles;
1080
- styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
1081
- results[property] = css[property];
1082
- return results;
1083
- });
1084
- if (!styles.opacity) styles.opacity = element.getOpacity();
1085
- return styles;
1086
- };
1087
- }
1088
-
1089
- Effect.Methods = {
1090
- morph: function(element, style) {
1091
- element = $(element);
1092
- new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
1093
- return element;
1094
- },
1095
- visualEffect: function(element, effect, options) {
1096
- element = $(element);
1097
- var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
1098
- new Effect[klass](element, options);
1099
- return element;
1100
- },
1101
- highlight: function(element, options) {
1102
- element = $(element);
1103
- new Effect.Highlight(element, options);
1104
- return element;
1105
- }
1106
- };
1107
-
1108
- $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
1109
- 'pulsate shake puff squish switchOff dropOut').each(
1110
- function(effect) {
1111
- Effect.Methods[effect] = function(element, options){
1112
- element = $(element);
1113
- Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
1114
- return element;
1115
- };
1116
- }
1117
- );
1118
-
1119
- $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
1120
- function(f) { Effect.Methods[f] = Element[f]; }
1121
- );
1122
-
1123
- Element.addMethods(Effect.Methods);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/excanvas.js DELETED
@@ -1,35 +0,0 @@
1
- // Copyright 2006 Google Inc.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
- document.createElement("canvas").getContext||(function(){var s=Math,j=s.round,F=s.sin,G=s.cos,V=s.abs,W=s.sqrt,k=10,v=k/2;function X(){return this.context_||(this.context_=new H(this))}var L=Array.prototype.slice;function Y(b,a){var c=L.call(arguments,2);return function(){return b.apply(a,c.concat(L.call(arguments)))}}var M={init:function(b){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var a=b||document;a.createElement("canvas");a.attachEvent("onreadystatechange",Y(this.init_,this,a))}},init_:function(b){b.namespaces.g_vml_||
15
- b.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML");b.namespaces.g_o_||b.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML");if(!b.styleSheets.ex_canvas_){var a=b.createStyleSheet();a.owningElement.id="ex_canvas_";a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=b.getElementsByTagName("canvas"),d=0;for(;d<c.length;d++)this.initElement(c[d])},
16
- initElement:function(b){if(!b.getContext){b.getContext=X;b.innerHTML="";b.attachEvent("onpropertychange",Z);b.attachEvent("onresize",$);var a=b.attributes;if(a.width&&a.width.specified)b.style.width=a.width.nodeValue+"px";else b.width=b.clientWidth;if(a.height&&a.height.specified)b.style.height=a.height.nodeValue+"px";else b.height=b.clientHeight}return b}};function Z(b){var a=b.srcElement;switch(b.propertyName){case "width":a.style.width=a.attributes.width.nodeValue+"px";a.getContext().clearRect();
17
- break;case "height":a.style.height=a.attributes.height.nodeValue+"px";a.getContext().clearRect();break}}function $(b){var a=b.srcElement;if(a.firstChild){a.firstChild.style.width=a.clientWidth+"px";a.firstChild.style.height=a.clientHeight+"px"}}M.init();var N=[],B=0;for(;B<16;B++){var C=0;for(;C<16;C++)N[B*16+C]=B.toString(16)+C.toString(16)}function I(){return[[1,0,0],[0,1,0],[0,0,1]]}function y(b,a){var c=I(),d=0;for(;d<3;d++){var f=0;for(;f<3;f++){var h=0,g=0;for(;g<3;g++)h+=b[d][g]*a[g][f];c[d][f]=
18
- h}}return c}function O(b,a){a.fillStyle=b.fillStyle;a.lineCap=b.lineCap;a.lineJoin=b.lineJoin;a.lineWidth=b.lineWidth;a.miterLimit=b.miterLimit;a.shadowBlur=b.shadowBlur;a.shadowColor=b.shadowColor;a.shadowOffsetX=b.shadowOffsetX;a.shadowOffsetY=b.shadowOffsetY;a.strokeStyle=b.strokeStyle;a.globalAlpha=b.globalAlpha;a.arcScaleX_=b.arcScaleX_;a.arcScaleY_=b.arcScaleY_;a.lineScale_=b.lineScale_}function P(b){var a,c=1;b=String(b);if(b.substring(0,3)=="rgb"){var d=b.indexOf("(",3),f=b.indexOf(")",d+
19
- 1),h=b.substring(d+1,f).split(",");a="#";var g=0;for(;g<3;g++)a+=N[Number(h[g])];if(h.length==4&&b.substr(3,1)=="a")c=h[3]}else a=b;return{color:a,alpha:c}}function aa(b){switch(b){case "butt":return"flat";case "round":return"round";case "square":default:return"square"}}function H(b){this.m_=I();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.fillStyle=this.strokeStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=k*1;this.globalAlpha=1;this.canvas=b;
20
- var a=b.ownerDocument.createElement("div");a.style.width=b.clientWidth+"px";a.style.height=b.clientHeight+"px";a.style.position="absolute";b.appendChild(a);this.element_=a;this.lineScale_=this.arcScaleY_=this.arcScaleX_=1}var i=H.prototype;i.clearRect=function(){this.element_.innerHTML=""};i.beginPath=function(){this.currentPath_=[]};i.moveTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"moveTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};
21
- i.lineTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"lineTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};i.bezierCurveTo=function(b,a,c,d,f,h){var g=this.getCoords_(f,h),l=this.getCoords_(b,a),e=this.getCoords_(c,d);Q(this,l,e,g)};function Q(b,a,c,d){b.currentPath_.push({type:"bezierCurveTo",cp1x:a.x,cp1y:a.y,cp2x:c.x,cp2y:c.y,x:d.x,y:d.y});b.currentX_=d.x;b.currentY_=d.y}i.quadraticCurveTo=function(b,a,c,d){var f=this.getCoords_(b,a),h=this.getCoords_(c,d),g={x:this.currentX_+
22
- 0.6666666666666666*(f.x-this.currentX_),y:this.currentY_+0.6666666666666666*(f.y-this.currentY_)};Q(this,g,{x:g.x+(h.x-this.currentX_)/3,y:g.y+(h.y-this.currentY_)/3},h)};i.arc=function(b,a,c,d,f,h){c*=k;var g=h?"at":"wa",l=b+G(d)*c-v,e=a+F(d)*c-v,m=b+G(f)*c-v,r=a+F(f)*c-v;if(l==m&&!h)l+=0.125;var n=this.getCoords_(b,a),o=this.getCoords_(l,e),q=this.getCoords_(m,r);this.currentPath_.push({type:g,x:n.x,y:n.y,radius:c,xStart:o.x,yStart:o.y,xEnd:q.x,yEnd:q.y})};i.rect=function(b,a,c,d){this.moveTo(b,
23
- a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath()};i.strokeRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.stroke();this.currentPath_=f};i.fillRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.fill();this.currentPath_=f};i.createLinearGradient=function(b,
24
- a,c,d){var f=new D("gradient");f.x0_=b;f.y0_=a;f.x1_=c;f.y1_=d;return f};i.createRadialGradient=function(b,a,c,d,f,h){var g=new D("gradientradial");g.x0_=b;g.y0_=a;g.r0_=c;g.x1_=d;g.y1_=f;g.r1_=h;return g};i.drawImage=function(b){var a,c,d,f,h,g,l,e,m=b.runtimeStyle.width,r=b.runtimeStyle.height;b.runtimeStyle.width="auto";b.runtimeStyle.height="auto";var n=b.width,o=b.height;b.runtimeStyle.width=m;b.runtimeStyle.height=r;if(arguments.length==3){a=arguments[1];c=arguments[2];h=g=0;l=d=n;e=f=o}else if(arguments.length==
25
- 5){a=arguments[1];c=arguments[2];d=arguments[3];f=arguments[4];h=g=0;l=n;e=o}else if(arguments.length==9){h=arguments[1];g=arguments[2];l=arguments[3];e=arguments[4];a=arguments[5];c=arguments[6];d=arguments[7];f=arguments[8]}else throw Error("Invalid number of arguments");var q=this.getCoords_(a,c),t=[];t.push(" <g_vml_:group",' coordsize="',k*10,",",k*10,'"',' coordorigin="0,0"',' style="width:',10,"px;height:",10,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var E=[];E.push("M11=",
26
- this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",j(q.x/k),",","Dy=",j(q.y/k),"");var p=q,z=this.getCoords_(a+d,c),w=this.getCoords_(a,c+f),x=this.getCoords_(a+d,c+f);p.x=s.max(p.x,z.x,w.x,x.x);p.y=s.max(p.y,z.y,w.y,x.y);t.push("padding:0 ",j(p.x/k),"px ",j(p.y/k),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",E.join(""),", sizingmethod='clip');")}else t.push("top:",j(q.y/k),"px;left:",j(q.x/k),"px;");t.push(' ">','<g_vml_:image src="',b.src,
27
- '"',' style="width:',k*d,"px;"," height:",k*f,'px;"',' cropleft="',h/n,'"',' croptop="',g/o,'"',' cropright="',(n-h-l)/n,'"',' cropbottom="',(o-g-e)/o,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};i.stroke=function(b){var a=[],c=P(b?this.fillStyle:this.strokeStyle),d=c.color,f=c.alpha*this.globalAlpha;a.push("<g_vml_:shape",' filled="',!!b,'"',' style="position:absolute;width:',10,"px;height:",10,'px;"',' coordorigin="0 0" coordsize="',k*10," ",k*10,'"',' stroked="',
28
- !b,'"',' path="');var h={x:null,y:null},g={x:null,y:null},l=0;for(;l<this.currentPath_.length;l++){var e=this.currentPath_[l];switch(e.type){case "moveTo":a.push(" m ",j(e.x),",",j(e.y));break;case "lineTo":a.push(" l ",j(e.x),",",j(e.y));break;case "close":a.push(" x ");e=null;break;case "bezierCurveTo":a.push(" c ",j(e.cp1x),",",j(e.cp1y),",",j(e.cp2x),",",j(e.cp2y),",",j(e.x),",",j(e.y));break;case "at":case "wa":a.push(" ",e.type," ",j(e.x-this.arcScaleX_*e.radius),",",j(e.y-this.arcScaleY_*e.radius),
29
- " ",j(e.x+this.arcScaleX_*e.radius),",",j(e.y+this.arcScaleY_*e.radius)," ",j(e.xStart),",",j(e.yStart)," ",j(e.xEnd),",",j(e.yEnd));break}if(e){if(h.x==null||e.x<h.x)h.x=e.x;if(g.x==null||e.x>g.x)g.x=e.x;if(h.y==null||e.y<h.y)h.y=e.y;if(g.y==null||e.y>g.y)g.y=e.y}}a.push(' ">');if(b)if(typeof this.fillStyle=="object"){var m=this.fillStyle,r=0,n={x:0,y:0},o=0,q=1;if(m.type_=="gradient"){var t=m.x1_/this.arcScaleX_,E=m.y1_/this.arcScaleY_,p=this.getCoords_(m.x0_/this.arcScaleX_,m.y0_/this.arcScaleY_),
30
- z=this.getCoords_(t,E);r=Math.atan2(z.x-p.x,z.y-p.y)*180/Math.PI;if(r<0)r+=360;if(r<1.0E-6)r=0}else{var p=this.getCoords_(m.x0_,m.y0_),w=g.x-h.x,x=g.y-h.y;n={x:(p.x-h.x)/w,y:(p.y-h.y)/x};w/=this.arcScaleX_*k;x/=this.arcScaleY_*k;var R=s.max(w,x);o=2*m.r0_/R;q=2*m.r1_/R-o}var u=m.colors_;u.sort(function(ba,ca){return ba.offset-ca.offset});var J=u.length,da=u[0].color,ea=u[J-1].color,fa=u[0].alpha*this.globalAlpha,ga=u[J-1].alpha*this.globalAlpha,S=[],l=0;for(;l<J;l++){var T=u[l];S.push(T.offset*q+
31
- o+" "+T.color)}a.push('<g_vml_:fill type="',m.type_,'"',' method="none" focus="100%"',' color="',da,'"',' color2="',ea,'"',' colors="',S.join(","),'"',' opacity="',ga,'"',' g_o_:opacity2="',fa,'"',' angle="',r,'"',' focusposition="',n.x,",",n.y,'" />')}else a.push('<g_vml_:fill color="',d,'" opacity="',f,'" />');else{var K=this.lineScale_*this.lineWidth;if(K<1)f*=K;a.push("<g_vml_:stroke",' opacity="',f,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',aa(this.lineCap),
32
- '"',' weight="',K,'px"',' color="',d,'" />')}a.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",a.join(""))};i.fill=function(){this.stroke(true)};i.closePath=function(){this.currentPath_.push({type:"close"})};i.getCoords_=function(b,a){var c=this.m_;return{x:k*(b*c[0][0]+a*c[1][0]+c[2][0])-v,y:k*(b*c[0][1]+a*c[1][1]+c[2][1])-v}};i.save=function(){var b={};O(this,b);this.aStack_.push(b);this.mStack_.push(this.m_);this.m_=y(I(),this.m_)};i.restore=function(){O(this.aStack_.pop(),
33
- this);this.m_=this.mStack_.pop()};function ha(b){var a=0;for(;a<3;a++){var c=0;for(;c<2;c++)if(!isFinite(b[a][c])||isNaN(b[a][c]))return false}return true}function A(b,a,c){if(!!ha(a)){b.m_=a;if(c)b.lineScale_=W(V(a[0][0]*a[1][1]-a[0][1]*a[1][0]))}}i.translate=function(b,a){A(this,y([[1,0,0],[0,1,0],[b,a,1]],this.m_),false)};i.rotate=function(b){var a=G(b),c=F(b);A(this,y([[a,c,0],[-c,a,0],[0,0,1]],this.m_),false)};i.scale=function(b,a){this.arcScaleX_*=b;this.arcScaleY_*=a;A(this,y([[b,0,0],[0,a,
34
- 0],[0,0,1]],this.m_),true)};i.transform=function(b,a,c,d,f,h){A(this,y([[b,a,0],[c,d,0],[f,h,1]],this.m_),true)};i.setTransform=function(b,a,c,d,f,h){A(this,[[b,a,0],[c,d,0],[f,h,1]],true)};i.clip=function(){};i.arcTo=function(){};i.createPattern=function(){return new U};function D(b){this.type_=b;this.r1_=this.y1_=this.x1_=this.r0_=this.y0_=this.x0_=0;this.colors_=[]}D.prototype.addColorStop=function(b,a){a=P(a);this.colors_.push({offset:b,color:a.color,alpha:a.alpha})};function U(){}G_vmlCanvasManager=
35
- M;CanvasRenderingContext2D=H;CanvasGradient=D;CanvasPattern=U})();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/loading.gif DELETED
Binary file
js/mageho/sortproducts/opentip.css DELETED
@@ -1,460 +0,0 @@
1
- /**
2
- ** http://www.opentip.org
3
- ** See opentip.js for the license.
4
- **
5
- ** One word about the different states when showing / hiding opentips.
6
- **
7
- ** An opentip starts with the .ot-completely-hidden class.
8
- ** When shown, it changes to .ot-becoming-visible, then to .ot-visible (depending
9
- ** on the length of the transition effect).
10
- ** When hidden, it changes to .ot-hidden, and then to .ot-completely-hidden (again:
11
- ** depending on the length of the transition effect).
12
- **/
13
- .ot-container {
14
- position: absolute;
15
- max-width: 300px;
16
- z-index: 100;
17
- }
18
- /**
19
- * Only using the position transition on fixed opentips, so the tip only moves
20
- * smoothly when it changes position due to browser viewport changes.
21
- */
22
- .ot-container.ot-fixed {
23
- -webkit-transition-property: left, top;
24
- -webkit-transition-duration: 0.2s, 0.2s;
25
- -moz-transition-property: left, top;
26
- -moz-transition-duration: 0.2s, 0.2s;
27
- }
28
- .ot-container.ot-completely-hidden {
29
- display: none;
30
- }
31
- .opentip {
32
- position: relative;
33
- font-size: 13px;
34
- line-height: 120%;
35
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
36
- -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
37
- -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
38
- }
39
- .opentip .title { font-weight: bold; }
40
- .opentip .content { width: auto !important;}
41
-
42
-
43
- .opentip .loadingIndication {
44
- display: none;
45
- padding: 10px 15px;
46
- background: url("loading.gif") center center no-repeat;
47
- width: 25px;
48
- height: 15px;
49
- }
50
- .opentip .loadingIndication span { display: none; }
51
- .ot-loading .opentip .loadingIndication { display: block; }
52
- .ot-loading .opentip .content { display: none; }
53
-
54
- .ot-buttons {
55
- position: absolute;
56
- right: 0;
57
- top: 0;
58
- }
59
-
60
- .ot-buttons .close {
61
- display: block;
62
- width: 15px;
63
- height: 15px;
64
- display: block;
65
- text-decoration: none;
66
- }
67
- .ot-buttons .close .canvas {
68
- position: relative;
69
- display: block;
70
- color: white; /* Read by JS and applied to canvas */
71
- background-color: rgba(0, 0, 0, 0.2); /* Read by JS and applied to canvas */
72
- }
73
-
74
- .ot-container .stem-container {
75
- position: absolute;
76
- width: 0;
77
- height: 0;
78
- }
79
- .ot-container .stem {
80
- position: absolute;
81
- overflow: hidden;
82
- color: #cccccc; /* JS will read this property to draw the stem in the right color. */
83
- /* background: rgba(255, 0, 0, 0.5);*/
84
- }
85
-
86
-
87
- .ot-container .left { left: 0; }
88
- .ot-container .center { left: 50%; }
89
- .ot-container .right { right: 0; }
90
- .ot-container .top { top: 0; }
91
- .ot-container .middle { top: 50%; }
92
- .ot-container .bottom { bottom: 0; }
93
-
94
-
95
-
96
- /**
97
-
98
- Styles
99
- ======
100
-
101
- Those are the different styles available in opentip.
102
-
103
- **/
104
-
105
- .style-standard .opentip {
106
- border: 1px solid #f2e37b;
107
- background-color: #fff18f;
108
- color: black;
109
- padding: 6px 10px;
110
- box-shadow: 2px 2px 7px rgba(0, 0, 0, 0.1);
111
- -moz-box-shadow: 2px 2px 7px rgba(0, 0, 0, 0.1);
112
- -webkit-box-shadow: 2px 2px 7px rgba(0, 0, 0, 0.1);
113
- }
114
- .style-standard .opentip .title {
115
- margin-bottom: 1px;
116
- }
117
- .style-standard .stem {
118
- color: #e3ca1b; /* JS will read this property to draw the stem in the right color. */
119
- }
120
- .style-standard .ot-buttons {
121
- top: -6px;
122
- right: -6px;
123
- }
124
- .style-standard .ot-buttons .close {
125
- width: 21px;
126
- height: 21px;
127
- }
128
- .style-standard .ot-buttons .close .canvas {
129
- background-color: rgba(255, 241, 143, 0.5);
130
- color: #a2932B;
131
- }
132
-
133
-
134
-
135
-
136
- .style-rounded .opentip {
137
- border: 7px solid #81b4da;
138
- background-color: #f9fbfc;
139
- color: #3f5d73;
140
- border-radius: 10px;
141
- -moz-border-radius: 10px;
142
- -webkit-border-radius: 10px;
143
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
144
- -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
145
- -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
146
- }
147
- .style-rounded .opentip .title {
148
- background: #81b4da;
149
- color: #f7fafd;
150
- padding: 0px 10px 4px 10px;
151
- }
152
- .style-rounded .opentip .content {
153
- padding: 6px 10px;
154
- }
155
- .style-rounded .stem {
156
- color: #c3ddf0;
157
- }
158
- .style-rounded .ot-buttons {
159
- top: -3px;
160
- right: -3px;
161
- }
162
- .style-rounded .ot-buttons .close {
163
- width: 21px;
164
- height: 21px;
165
- }
166
- .style-rounded .ot-buttons .close .canvas {
167
- background-color: #81B4DA;
168
- }
169
-
170
- .style-slick .opentip {
171
- border: 1px solid #eeeeee;
172
- background: #f7f7f7;
173
- border-radius: 3px;
174
- -moz-border-radius: 3px;
175
- -webkit-border-radius: 3px;
176
- }
177
- .style-slick .opentip .title {
178
- /* color: #49677e !important; */
179
- color:#fff !important;
180
- padding: 5px 10px 3px 10px !important;
181
- border-bottom: 1px solid #eeeeee !important;
182
- }
183
- .style-slick .opentip .content {
184
- padding: 6px 10px;
185
- border-top: 1px solid #fefefe;
186
- }
187
- .style-slick .stem {
188
- color: #cccccc;
189
- }
190
- .style-slick .ot-buttons {
191
- right: -7px;
192
- top: -5px;
193
- }
194
- .style-slick .ot-buttons .close {
195
- height: 19px;
196
- width: 19px;
197
- }
198
- .style-slick .ot-buttons .close .canvas {
199
- background-color: rgba(0, 0, 0, 0.2);
200
- }
201
-
202
-
203
- .style-glass .opentip {
204
- background: white;
205
- background: rgba(255, 255, 255, 0.9);
206
- border-radius: 5px;
207
- -moz-border-radius: 5px;
208
- -webkit-border-radius: 5px;
209
- box-shadow: 0 0 15px rgba(51, 113, 136, 0.5);
210
- -moz-box-shadow: 0 0 15px rgba(51, 113, 136, 0.5);
211
- -webkit-box-shadow: 0 0 15px rgba(51, 113, 136, 0.5);
212
- padding: 20px 30px;
213
- }
214
- .style-glass .opentip .title {
215
- color: #316F89;
216
- font-family: serif;
217
- font-style: italic;
218
- margin: 0 0 20px 0;
219
- font-size: 16px;
220
- }
221
- .style-glass .opentip .content {
222
- color: #333333;
223
- }
224
- .style-glass .stem {
225
- color: #ffffff;
226
- }
227
- .style-glass .ot-buttons {
228
- right: -3px;
229
- top: -3px;
230
- }
231
- .style-glass .ot-buttons .close {
232
- width: 25px;
233
- height: 25px;
234
- }
235
- .style-glass .ot-buttons .close .canvas {
236
- background-color: #F7BA00;
237
- }
238
-
239
- /**
240
-
241
- IE 6 HACKS
242
- ==========
243
-
244
- **/
245
-
246
- /*\*/
247
- .ot-buttons {
248
- z-index: 110;
249
- }
250
- .opentip {
251
- z-index: 110;
252
- }
253
- .opentipIFrame {
254
- position: absolute;
255
- top: 0;
256
- left: 0;
257
- border: none;
258
- background: none;
259
- margin: 0;
260
- padding: 0;
261
- display:none;
262
- /*sorry for IE5*/ display/**/:block;/*sorry for IE5*/
263
- z-index:-1;/*must have*/
264
- filter:mask();/*must have*/
265
- }
266
-
267
- .style-glass .opentip {
268
- border: 1px solid #bbbbbb;
269
- }
270
- /**/
271
-
272
-
273
-
274
-
275
- /**
276
-
277
- CSS3 Transitions
278
- ================
279
-
280
- The definitions that follow here, are only meant for browsers that support css3
281
- transitions.
282
-
283
- So the syntax I'm going to use, is really meant for more modern browsers than
284
- IE6.
285
-
286
-
287
-
288
- To define a show effect, you have to define the position you want to come from
289
- as the .ot-completely-hidden property (in combination with your
290
- .ot-show-effectName).
291
-
292
- To define a hide effect, you do the same, but for .ot-hidden (in combination
293
- with your .ot-show-effectName).
294
-
295
- **/
296
-
297
-
298
- .ot-container.ot-css3 {
299
- -webkit-transition-duration: 1s; /* Well be reset by JS */
300
- -webkit-transition-property: opacity, -webkit-transform;
301
- -moz-transition-duration: 1s; /* Well be reset by JS */
302
- -moz-transition-property: opacity, -moz-transform;
303
- -o-transition-duration: 1s; /* Well be reset by JS */
304
- -o-transition-property: opacity, -o-transform;
305
-
306
- opacity: 1;
307
- }
308
-
309
- .ot-container.ot-css3.ot-completely-hidden {
310
- display: none;
311
- }
312
-
313
-
314
-
315
-
316
-
317
- /** Appear / Fade**/
318
- .ot-container.ot-css3.ot-becoming-visible.ot-show-appear,
319
- .ot-container.ot-css3.ot-hidden.ot-hide-fade {
320
- opacity: 0;
321
- }
322
-
323
-
324
-
325
- /** Grow / Shrink **/
326
- .ot-container.ot-css3.ot-becoming-visible.ot-show-grow,
327
- .ot-container.ot-css3.ot-hidden.ot-hide-shrink {
328
- -webkit-transform: scale(0);
329
- -moz-transform: scale(0);
330
- -o-transform: scale(0);
331
- }
332
-
333
-
334
-
335
- /** Blind/Slide down / Blind up**/
336
- .ot-container.ot-css3.ot-becoming-visible.ot-show-blindDown,
337
- .ot-container.ot-css3.ot-becoming-visible.ot-show-slideDown,
338
- .ot-container.ot-css3.ot-hidden.ot-hide-blindUp {
339
- -webkit-transform: scaleY(0);
340
- -moz-transform: scaleY(0);
341
- -o-transform: scaleY(0);
342
- opacity: 0;
343
- }
344
-
345
-
346
- /** Condense / Puff **/
347
- .ot-container.ot-css3.ot-becoming-visible.ot-show-condense,
348
- .ot-container.ot-css3.ot-hidden.ot-hide-puff {
349
- -webkit-transform: scale(5);
350
- -moz-transform: scale(5);
351
- -o-transform: scale(5);
352
- opacity: 0;
353
- }
354
-
355
- /** Rotate **/
356
- .ot-container.ot-css3.ot-becoming-visible.ot-show-rotate {
357
- -webkit-transform: scale(3) rotate(-500deg);
358
- -moz-transform: scale(3) rotate(-500deg);
359
- -o-transform: scale(3) rotate(-500deg);
360
- opacity: 0;
361
- }
362
- .ot-container.ot-css3.ot-hidden.ot-hide-rotate {
363
- -webkit-transform: scale(3) rotate(500deg);
364
- -moz-transform: scale(3) rotate(500deg);
365
- -o-transform: scale(3) rotate(500deg);
366
- opacity: 0;
367
- }
368
-
369
-
370
-
371
-
372
-
373
-
374
-
375
-
376
-
377
-
378
-
379
-
380
- /**
381
-
382
- Content design
383
- ==============
384
-
385
- Nicer input fields, etc...
386
-
387
- */
388
-
389
-
390
- .opentip label {
391
- margin-bottom: 3px;
392
- margin-top: 10px;
393
- display: block;
394
- }
395
- .opentip input, .opentip textarea {
396
- padding: 5px 6px;
397
- border: 1px solid rgba(100, 100, 100, 0.2);
398
- background: rgba(255,255,255,0.5);
399
- display: block;
400
- width: 100%;
401
- margin: 3px 0 10px 0;
402
- -moz-border-radius: 2px;
403
- -webkit-border-radius: 2px;
404
- -moz-box-sizing: border-box;
405
- -webkit-box-sizing: border-box;
406
- }
407
- .opentip input:focus, .opentip textarea:focus {
408
- border-color: rgba(100, 100, 100, 0.2);
409
- -moz-box-shadow: 0 0 10px rgba(0,0,0,0.2);
410
- -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2);
411
- }
412
-
413
- .opentip button {
414
- margin-top: 20px;
415
- display: block;
416
- -moz-box-sizing: border-box;
417
- -webkit-box-sizing: border-box;
418
- box-sizing: border-box;
419
- width: 100%;
420
-
421
-
422
- border: 1px solid rgba(247, 186, 0, 0.8);
423
- background: rgba(247, 186, 0, 0.9);
424
- font-size: 14px;
425
- line-height: 14px;
426
- padding: 10px 10px;
427
- position: relative;
428
- color: rgba(255,255,255, 1);
429
- text-shadow: 0 0 10px rgba(255,255,255,0.3);
430
- text-align: center;
431
- font-weight: bold;
432
- font-family: serif;
433
- font-style: italic;
434
- text-decoration: none;
435
- margin: 20px 0 0 0;
436
- cursor: pointer;
437
- -moz-border-radius: 2px;
438
- -webkit-border-radius: 2px;
439
- -moz-box-shadow: 0 0 4px rgba(0,0,0,0.2),
440
- 0 -2px 10px rgba(255, 255, 255, 0.4) inset;
441
- -webkit-box-shadow: 0 0 4px rgba(0,0,0,0.2),
442
- 0 -2px 10px rgba(255, 255, 255, 0.4) inset;
443
- }
444
- .opentip button {
445
- padding: 8px 6px;
446
- }
447
- .button:hover, button:hover {
448
- -moz-box-shadow: 0 0 6px rgba(247, 192, 25, 1),
449
- 0 -2px 10px rgba(255, 255, 255, 0.6) inset;
450
- text-shadow: 0 0 4px rgba(255,255,255,1);
451
- }
452
-
453
-
454
-
455
- /** IE 6 HACKS **/
456
- /*\*/
457
- .opentip input, .opentip textarea, .opentip button {
458
- width: 200px;
459
- }
460
- /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/opentip.js DELETED
@@ -1,1285 +0,0 @@
1
- /**
2
- ** More info at http://www.opentip.org
3
- **
4
- ** Copyright (c) 2009, Matias Meno
5
- ** Graphics by Tjandra Mayerhold
6
- **
7
- ** Permission is hereby granted, free of charge, to any person obtaining a copy
8
- ** of this software and associated documentation files (the "Software"), to deal
9
- ** in the Software without restriction, including without limitation the rights
10
- ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- ** copies of the Software, and to permit persons to whom the Software is
12
- ** furnished to do so, subject to the following conditions:
13
- **
14
- ** The above copyright notice and this permission notice shall be included in
15
- ** all copies or substantial portions of the Software.
16
- **
17
- ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- ** THE SOFTWARE.
24
- **
25
- **/
26
-
27
-
28
- /**
29
- ** Usage:
30
- **
31
- ** <div onmouseover="javascript:Tips.add(this, event, 'Content', { options });"></div>
32
- **
33
- ** or externally:
34
- **
35
- ** $('elementId').addTip('Content', { options });
36
- **
37
- ** For a full documentation, please visit http://www.opentip.org/documentation
38
- **/
39
-
40
-
41
-
42
- /**
43
- * Namespace and helper functions for opentips.
44
- */
45
- var Opentip = {
46
-
47
- Version: '1.4.4',
48
- REQUIRED_PROTOTYPE_VERSION: '1.6.0',
49
- REQUIRED_SCRIPTACULOUS_VERSION: '1.8.0',
50
- STICKS_OUT_TOP: 1,
51
- STICKS_OUT_BOTTOM: 2,
52
- STICKS_OUT_LEFT: 1,
53
- STICKS_OUT_RIGHT: 2,
54
- cached: {},
55
- debugging: false,
56
- load: function() {
57
- function getComparableVersion(version) {var v = version.split('.');return parseInt(v[0])*100000 + parseInt(v[1])*1000 + parseInt(v[2]);}
58
- if((typeof Prototype === 'undefined') || (typeof Element === 'undefined') || (typeof Element.Methods === 'undefined') || (getComparableVersion(Prototype.Version) < getComparableVersion(Opentip.REQUIRED_PROTOTYPE_VERSION))) {throw("Opentip requires the Prototype JavaScript framework >= " + Opentip.REQUIRED_PROTOTYPE_VERSION);}
59
-
60
- Opentip.useCss3Transitions = Opentip.supports('transition');
61
- Opentip.useScriptaculousTransitions = ! Opentip.useCss3Transitions;
62
-
63
- if (Opentip.useCss3Transitions) Opentip.debug('Using CSS3 transitions.');
64
-
65
- if((typeof Scriptaculous === 'undefined') || (typeof Effect === 'undefined') || (getComparableVersion(Scriptaculous.Version) < getComparableVersion(Opentip.REQUIRED_SCRIPTACULOUS_VERSION))) {
66
- Opentip.debug('No scriptaculous available. Disabling scriptaculous transitions.');
67
- Opentip.useScriptaculousTransitions = false;
68
- }
69
- },
70
- debug: function() {if (this.debugging && typeof console !== 'undefined' && typeof console.debug !== 'undefined') console.debug.apply(console, arguments);},
71
- IEVersion: function() {
72
- if (typeof Opentip.cached.IEVersion !== 'undefined') return Opentip.cached.IEVersion;
73
- if (Prototype.Browser.IE) {
74
- var version = navigator.userAgent.match('MSIE ([\\d.]+)');
75
- var IEVersion = version ? (parseFloat(version[1])) : false;
76
- }
77
- else IEVersion = false;
78
- Opentip.cached.IEVersion = IEVersion;
79
- return IEVersion;
80
- },
81
- objectIsEvent: function(obj) {
82
- // There must be a better way of doing this.
83
- return (typeof(obj) == 'object' && obj.type && obj.screenX);
84
- },
85
- useIFrame: function() {return Opentip.IEVersion() ? (Opentip.IEVersion() <= 6) : false;},
86
- lastTipId: 1,
87
- lastZIndex: 100,
88
- documentIsLoaded: false,
89
- postponeCreation: function(createFunction) {
90
- if (Opentip.documentIsLoaded || !Opentip.IEVersion()) createFunction();
91
- else {
92
- Event.observe(window, 'load', createFunction); // Sorry IE users but... well: get another browser!
93
- }
94
- },
95
-
96
- // Mimics scriptaculous Builder.node behaviour
97
- element: function(tagName, attributes, children) {
98
- if (Object.isArray(attributes) || Object.isString(attributes) || Object.isElement(attributes)) {
99
- children = attributes;
100
- attributes = null;
101
- }
102
-
103
- var element = new Element(tagName, attributes || {});
104
-
105
- // This is a prototype 1.6 bug, that doesn't apply the className to IE8 elements.
106
- // Thanks to Alexander Shakhnovsky for finding the bug, and pinpointing the problem.
107
- if(attributes && attributes['className']) {
108
- attributes['className'].split(' ').each(function(class_name){element.addClassName(class_name);});
109
- }
110
-
111
- if (children) {
112
- if (Object.isArray(children)) {
113
- children.each(function(child) {
114
- element.insert({bottom: child});
115
- });
116
- }
117
- else {
118
- element.insert({bottom: children});
119
- }
120
- }
121
- return element;
122
- },
123
-
124
- // In the future every position attribute will go through this method.
125
- sanitizePosition: function(arrayPosition) {
126
- var position;
127
- if (Object.isArray(arrayPosition)) {
128
- var positionString = '';
129
- if (arrayPosition[0] == 'center') {
130
- positionString = arrayPosition[1];
131
- }
132
- else if (arrayPosition[1] == 'middle') {
133
- positionString = arrayPosition[0];
134
- }
135
- else {
136
- positionString = arrayPosition[1] + arrayPosition[0].capitalize();
137
- }
138
- if (Opentip.position[positionString] === undefined) throw 'Unknown position: ' + positionString;
139
- position = Opentip.position[positionString];
140
- }
141
- else if (Object.isString(arrayPosition)) {
142
- if (Opentip.position[arrayPosition] === undefined) throw 'Unknown position: ' + arrayPosition;
143
- position = Opentip.position[arrayPosition];
144
- }
145
- return parseInt(position);
146
- },
147
-
148
-
149
- /* Browser support testing */
150
- vendors: 'Khtml Ms O Moz Webkit'.split(' '),
151
- testDiv: document.createElement('div'),
152
- supports: function(prop) {
153
- if ( prop in Opentip.testDiv.style ) return true;
154
-
155
- prop = prop.ot_ucfirst();
156
-
157
- return Opentip.vendors.any(function(vendor) {
158
- return vendor + prop in Opentip.testDiv.style;
159
- });
160
- }
161
- };
162
-
163
- String.prototype.ot_ucfirst = function() {
164
- return this.replace(/^\w/, function(val) {return val.toUpperCase();});
165
- };
166
-
167
- Opentip.load();
168
-
169
-
170
-
171
-
172
-
173
- /**
174
- * The standard style.
175
- */
176
-
177
- Opentip.styles = {
178
- standard: {
179
- // This style contains all default values for other styles.
180
- // POSITION : [ 'left|right|center', 'top|bottom|middle' ]
181
- // COORDINATE : [ XVALUE, YVALUE ] (integers)
182
- title: null,
183
- className: 'standard', // The class name to be used in the stylesheet
184
- stem: false, // false (no stem) || true (stem at tipJoint position) || POSITION (for stems in other directions)
185
- delay: null, // float (in seconds - if null, the default is used: 0.2 for mouseover, 0 for click)
186
- hideDelay: 0.1, // --
187
- fixed: false, // If target is not null, elements are always fixed.
188
- showOn: 'mouseover', // string (the observe string of the trigger element, eg: click, mouseover, etc..) || 'creation' (the tooltip will show when being created) || null if you want to handle it yourself.
189
- hideTrigger: 'trigger', // 'trigger' | 'tip' | 'target' | 'closeButton' | ELEMENT | ELEMENT_ID || array containing any of the previous
190
- hideOn: null, // string (event eg: click) || array of event strings if multiple hideTriggers || null (let Opentip decide)
191
- offset: [ 0, 0 ], // COORDINATE
192
- containInViewport: true, // Whether the targetJoint/tipJoint should be changed if the tooltip is not in the viewport anymore.
193
- autoOffset: true, // If set to true, offsets are calculated automatically to position the tooltip. (pixels are added if there are stems for example)
194
- showEffect: 'appear', // scriptaculous or CSS3 (in opentip.css) effect
195
- fallbackShowEffect: 'appear', // At tip creation, this effect will override the showEffect, if useScriptaculousTransitions == true, and the showEffect does not exist.
196
- hideEffect: 'fade',
197
- fallbackHideEffect: 'appear',
198
- showEffectDuration: 0.3,
199
- hideEffectDuration: 0.2,
200
- stemSize: 8, // integer
201
- tipJoint: [ 'left', 'top' ], // POSITION
202
- target: null, // null (no target, opentip uses mouse as target) || true (target is the triggerElement) || elementId|element (for another element)
203
- targetJoint: null, // POSITION (Ignored if target == null) || null (targetJoint is the opposite of tipJoint)
204
- ajax: false, // Ajax options. eg: { url: 'yourUrl.html', options: { ajaxOptions... } } or { options: { ajaxOptions } /* This will use the href of the A element the tooltip is attached to */ }
205
- group: null, // You can group opentips together. So when a tooltip shows, it looks if there are others in the same group, and hides them.
206
- escapeHtml: false,
207
- style: null
208
- },
209
- slick: {
210
- className: 'slick',
211
- stem: true
212
- },
213
- rounded: {
214
- className: 'rounded',
215
- stem: true
216
- },
217
- glass: {
218
- className: 'glass'
219
- }
220
- };
221
- Opentip.defaultStyle = 'standard'; // Change this to the style name you want your tooltips to have.
222
-
223
-
224
-
225
- Opentip.position = {
226
- top: 0,
227
- topRight: 1,
228
- right: 2,
229
- bottomRight: 3,
230
- bottom: 4,
231
- bottomLeft: 5,
232
- left: 6,
233
- topLeft: 7
234
- };
235
-
236
-
237
-
238
- /**
239
- * On document load
240
- */
241
- Event.observe(window, Opentip.IEVersion() ? 'load' : 'dom:loaded', function() {
242
- Opentip.documentIsLoaded = true;
243
-
244
-
245
- var htmlOptionNames = [];
246
- for (var i in Opentip.styles.standard) {
247
- htmlOptionNames.push(i.underscore().dasherize());
248
- }
249
-
250
- // Go through all elements, and look for elements that have inline element
251
- // opentip definitions.
252
- $$('[data-ot]').each(function(element) {
253
- var options = {};
254
- element = $(element);
255
-
256
- var content = element.readAttribute('data-ot');
257
-
258
- if (content === '' || content === 'true' || content === 'yes') {
259
- content = element.readAttribute('title');
260
- element.title = '';
261
- }
262
-
263
-
264
- content || (content = '');
265
-
266
- htmlOptionNames.each(function(optionName) {
267
- var optionValue;
268
- if (optionValue = element.readAttribute('data-ot-' + optionName)) {
269
- try {
270
- // See if it's a JSON string.
271
- optionValue = optionValue.gsub("'", '"').evalJSON();
272
- }
273
- catch (err) {
274
- // Well, it's not.
275
- }
276
-
277
- options[optionName.camelize()] = optionValue;
278
- }
279
- });
280
-
281
- element.addTip(content, options);
282
- });
283
- });
284
-
285
-
286
-
287
-
288
-
289
-
290
- var Tips = {
291
- list: [],
292
- append: function(tip) {this.list.push(tip);},
293
- remove: function(element) {
294
- if (!element.element) var tip = this.list.find(function(t) {return t.triggerElement === element});
295
- else var tip = this.list.find(function(t) {return t === element});
296
- if (tip) {
297
- tip.deactivate();
298
- tip.destroyAllElements();
299
- this.list = this.list.without(tip);
300
- }
301
- },
302
- add: function(element) {
303
- if (element._opentipAddedTips) {
304
- /* TODO: Now it just returns the first found... try to find the correct one. */
305
- var tip = this.list.find(function(t) {return (t.triggerElement === element);});
306
- if (tip.options.showOn == 'creation') tip.show();
307
- tip.debug('Using an existing opentip.');
308
- return;
309
- } else setTimeout(function() {element._opentipAddedTips = true;}, 1); // I added a timeout, so that tooltips, defined in an onmouseover or onclick event, will show.
310
-
311
- Opentip.debug('Creating new opentip');
312
-
313
- var tipArguments = [];
314
-
315
- $A(arguments).each(function(arg, idx) {
316
- if (idx == 1 && !Opentip.objectIsEvent(arg)) tipArguments.push(null);
317
- tipArguments.push(arg);
318
- });
319
-
320
-
321
- // Creating the tooltip object, but not yet activating it, or creating the container elements.
322
- var tooltip = new TipClass(tipArguments[0], tipArguments[1], tipArguments[2], tipArguments[3], tipArguments[4]);
323
-
324
- this.append(tooltip);
325
-
326
- var self = this;
327
- var createTip = function() {
328
- tooltip.create(tipArguments[1]); // Passing the event.
329
- }
330
-
331
- Opentip.postponeCreation(createTip);
332
-
333
- return tooltip;
334
- },
335
- hideGroup: function(groupName) {
336
- this.list.findAll(function(t) {return (t.options.group == groupName);}).invoke('doHide');
337
- },
338
- abortShowingGroup: function(groupName) {
339
- this.list.findAll(function(t) {return (t.options.group == groupName);}).invoke('abortShowing');
340
- }
341
- };
342
-
343
- var Tip = function() { return Tips.add.apply(Tips, arguments); };
344
-
345
- Element.addMethods({
346
- addTip: function(element) {
347
- element = $(element);
348
- Tips.add.apply(Tips, arguments);
349
- return element;
350
- },
351
- setCss3Style: function(element) {
352
- element = $(element);
353
- var style = {};
354
- for (var propertyName in arguments[1]) {
355
- var css3PropertyName = propertyName.ot_ucfirst();
356
- var css3PropertyValue = arguments[1][propertyName];
357
- Opentip.vendors.each(function(vendor) {
358
- style[vendor + css3PropertyName] = css3PropertyValue;
359
- element.setStyle(style);
360
- });
361
- }
362
- return element;
363
- }
364
- });
365
-
366
-
367
- var TipClass = Class.create({
368
- debug: function() {
369
- var newArguments = Array.from(arguments);
370
- newArguments.unshift('ID:', this.id, '|');
371
- Opentip.debug.apply(Opentip, newArguments);
372
- },
373
- initialize: function(element, evt) {
374
- this.id = Opentip.lastTipId ++;
375
-
376
- element = $(element);
377
-
378
- this.triggerElement = element;
379
-
380
- this.loaded = false; // for ajax
381
- this.loading = false; // for ajax
382
-
383
- this.visible = false;
384
- this.waitingToShow = false;
385
- this.waitingToHide = false;
386
-
387
- this.lastPosition = {left: 0, top: 0};
388
- this.dimensions = [ 100, 50 ]; // Just some initial values.
389
-
390
- var options = {};
391
- this.content = '';
392
-
393
- if (typeof(arguments[2]) == 'object') {options = Object.clone(arguments[2]);}
394
- else if (typeof(arguments[3]) == 'object') {this.setContent(arguments[2]);options = Object.clone(arguments[3]);}
395
- else if (typeof(arguments[4]) == 'object') {this.setContent(arguments[2]);options = Object.clone(arguments[4]);options.title = arguments[3];}
396
- else {
397
- if (Object.isString(arguments[2]) || Object.isFunction(arguments[2])) this.setContent(arguments[2]);
398
- if (Object.isString(arguments[3])) options.title = arguments[3];
399
- }
400
-
401
- // Use the type of the html event (eg: onclick="") if called in an event.
402
- if (!options.showOn && evt) options.showOn = evt.type;
403
-
404
- // If the url of an Ajax request is not set, get it from the link it's attached to.
405
- if (options.ajax && !options.ajax.url) {
406
- if (this.triggerElement.tagName.toLowerCase() == 'a') {
407
- if (typeof(options.ajax) != 'object') options.ajax = { };
408
- options.ajax.url = this.triggerElement.href;
409
- } else {options.ajax = false;}
410
- }
411
-
412
- // If the event is 'click', no point in following a link
413
- if (options.showOn == 'click' && this.triggerElement.tagName.toLowerCase() == 'a') {if (evt) {evt.stop();}this.triggerElement.observe('click', function(e) {e.stop();});}
414
-
415
-
416
- options.style || (options.style = Opentip.defaultStyle);
417
-
418
- var styleOptions = Object.extend({ }, Opentip.styles.standard); // Copy all standard options.
419
- if (options.style != 'standard') Object.extend(styleOptions, Opentip.styles[options.style]);
420
-
421
- options = Object.extend(styleOptions, options);
422
-
423
-
424
- options.target && (options.fixed = true);
425
-
426
-
427
- if (options.stem === true) options.stem = options.tipJoint;
428
- if (options.target === true) options.target = this.triggerElement;
429
- else if (options.target) options.target = $(options.target);
430
-
431
-
432
- this.currentStemPosition = options.stem;
433
-
434
-
435
- if (options.delay === null) {
436
- if (options.showOn == 'mouseover') options.delay = 0.2;
437
- else options.delay = 0
438
- }
439
-
440
- if (Opentip.useScriptaculousTransitions) {
441
- if (options.showEffect && ! Effect[options.showEffect.ot_ucfirst()]) {
442
- this.debug('Using fallback show effect "' + options.fallbackShowEffect + '" instead of "' + options.showEffect + '"');
443
- options.showEffect = options.fallbackShowEffect;
444
- }
445
- if (options.hideEffect && ! Effect[options.hideEffect.ot_ucfirst()]) {
446
- this.debug('Using fallback hide effect "' + options.fallbackHideEffect + '" instead of "' + options.hideEffect + '"');
447
- options.hideEffect = options.fallbackHideEffect;
448
- }
449
- }
450
-
451
- if (options.targetJoint == null) {
452
- options.targetJoint = [];
453
- options.targetJoint[0] = options.tipJoint[0] == 'left' ? 'right' : (options.tipJoint[0] == 'right' ? 'left' : 'center');
454
- options.targetJoint[1] = options.tipJoint[1] == 'top' ? 'bottom' : (options.tipJoint[1] == 'bottom' ? 'top' : 'middle');
455
- }
456
-
457
- this.options = options;
458
-
459
- this.options.showTriggerElementsWhenHidden = [];
460
-
461
- if (this.options.showOn && this.options.showOn != 'creation') {
462
- this.options.showTriggerElementsWhenHidden.push({element: this.triggerElement, event: this.options.showOn});
463
- }
464
-
465
- this.options.showTriggerElementsWhenVisible = [];
466
-
467
-
468
- this.options.hideTriggerElements = [];
469
- },
470
- /**
471
- * This builds the container, and sets the correct hide trigger.
472
- * Since it's a problem for IE to create elements when the page is not fully
473
- * loaded, this function has to be posponed until the website is fully loaded.
474
- *
475
- * This function also activates the tooltip.
476
- **/
477
- create: function(evt) {
478
- this.buildContainer();
479
-
480
- if (this.options.hideTrigger) {
481
- var hideOnEvent = null;
482
- var hideTriggerElement = null;
483
-
484
- if (!(this.options.hideTrigger instanceof Array)) {
485
- this.options.hideTrigger = [this.options.hideTrigger];
486
- }
487
-
488
- this.options.hideTrigger.each(function(hideTrigger, i) {
489
-
490
- var hideOnOption = (this.options.hideOn instanceof Array) ? this.options.hideOn[i] : this.options.hideOn;
491
-
492
- switch (hideTrigger) {
493
- case 'trigger':
494
- hideOnEvent = hideOnOption ? hideOnOption : 'mouseout';
495
- hideTriggerElement = this.triggerElement;
496
- break;
497
- case 'tip':
498
- hideOnEvent = hideOnOption ? hideOnOption : 'mouseover';
499
- hideTriggerElement = this.container;
500
- break;
501
- case 'target':
502
- hideOnEvent = hideOnOption ? hideOnOption : 'mouseover';
503
- hideTriggerElement = this.options.target;
504
- break;
505
- case 'closeButton':break;
506
- default:
507
- hideOnEvent = hideOnOption ? hideOnOption : 'mouseover';
508
- hideTriggerElement = $(hideTrigger);
509
- break;
510
- }
511
- if (hideTriggerElement) {
512
- this.options.hideTriggerElements.push({element: hideTriggerElement, event: hideOnEvent});
513
- if (hideOnEvent == 'mouseout') {
514
- // When the hide trigger is mouseout, we have to attach a mouseover trigger to that element, so the tooltip doesn't disappear when
515
- // hovering child elements. (Hovering children fires a mouseout mouseover event)
516
- this.options.showTriggerElementsWhenVisible.push({element: hideTriggerElement, event: 'mouseover'});
517
- }
518
- }
519
- }.bind(this));
520
- }
521
-
522
- this.activate();
523
-
524
- if (evt || this.options.showOn == 'creation') this.show(evt);
525
- },
526
- activate: function() {
527
- this.bound = {};
528
- this.bound.doShow = this.doShow.bindAsEventListener(this);
529
- this.bound.show = this.show.bindAsEventListener(this);
530
- this.bound.doHide = this.doHide.bindAsEventListener(this);
531
- this.bound.hide = this.hide.bindAsEventListener(this);
532
- this.bound.position = this.position.bindAsEventListener(this);
533
-
534
- if (this.options.showEffect || this.options.hideEffect) this.queue = {limit: 1, position: 'end', scope: this.container.identify()};
535
-
536
- // The order is important here! Do not reverse.
537
- this.setupObserversForReallyHiddenTip();
538
- this.setupObserversForHiddenTip();
539
- },
540
- deactivate: function() {
541
- this.debug('Deactivating tooltip.');
542
- this.doHide();
543
- this.setupObserversForReallyHiddenTip();
544
- },
545
- buildContainer: function() {
546
- this.container = $(Opentip.element('div', {className: 'ot-container ot-completely-hidden style-' + this.options.className + (this.options.ajax ? ' ot-loading' : '') + (this.options.fixed ? ' ot-fixed' : '')}));
547
- if (Opentip.useCss3Transitions) {
548
- this.container.setCss3Style({'transitionDuration': '0s'}); // To make sure the initial state doesn't fade
549
-
550
- this.container.addClassName('ot-css3');
551
- if (this.options.showEffect) {
552
- this.container.addClassName('ot-show-' + this.options.showEffect);
553
- }
554
- if (this.options.hideEffect) {
555
- this.container.addClassName('ot-hide-' + this.options.hideEffect);
556
- }
557
- }
558
- if (Opentip.useScriptaculousTransitions) this.container.setStyle({display: 'none'});
559
- },
560
- buildElements: function() {
561
- var stemCanvas;
562
- var closeButtonCanvas;
563
- if (this.options.stem) {
564
- var stemOffset = '-' + this.options.stemSize + 'px';
565
- this.container.appendChild(Opentip.element('div', {className: 'stem-container ' + this.options.stem[0] + ' ' + this.options.stem[1]}, stemCanvas = Opentip.element('canvas', {className: 'stem'})));
566
- }
567
- var self = this;
568
- var content = [];
569
- var headerContent = [];
570
- if (this.options.title) headerContent.push(Opentip.element('div', {className: 'title'}, this.options.title));
571
-
572
- content.push(Opentip.element('div', {className: 'header'}, headerContent));
573
- content.push($(Opentip.element('div', {className: 'content'}))); // Will be updated by updateElementContent()
574
- if (this.options.ajax) {content.push($(Opentip.element('div', {className: 'loadingIndication'}, Opentip.element('span', 'Loading...'))));}
575
- this.tooltipElement = $(Opentip.element('div', {className: 'opentip'}, content));
576
-
577
- this.container.appendChild(this.tooltipElement);
578
-
579
- var buttons = this.container.appendChild(Opentip.element('div', {className: 'ot-buttons'}));
580
- var drawCloseButton = false;
581
- if (this.options.hideTrigger && this.options.hideTrigger.include('closeButton')) {
582
- buttons.appendChild(Opentip.element('a', {href: 'javascript:undefined', className: 'close'}, closeButtonCanvas = Opentip.element('canvas', { className: 'canvas' })));
583
- // The canvas has to have a className assigned, because IE < 9 doesn't know the element, and won't assign any css to it.
584
- drawCloseButton = true;
585
- }
586
-
587
- if (Opentip.useIFrame()) this.iFrameElement = this.container.appendChild($(Opentip.element('iframe', {className: 'opentipIFrame', src: 'javascript:false;'})).setStyle({display: 'none', zIndex: 100}).setOpacity(0));
588
-
589
- document.body.appendChild(this.container);
590
-
591
- if (typeof G_vmlCanvasManager !== "undefined") {
592
- if (stemCanvas) G_vmlCanvasManager.initElement(stemCanvas);
593
- if (closeButtonCanvas) G_vmlCanvasManager.initElement(closeButtonCanvas);
594
- }
595
-
596
- if (drawCloseButton) this.drawCloseButton();
597
- },
598
- drawCloseButton: function() {
599
- var canvasElement = this.container.down('.ot-buttons canvas');
600
- var containerElement = this.container.down('.ot-buttons .close');
601
- var size = parseInt(containerElement.getStyle('width')) || 20; // Opera 10 has a bug here.. it seems to never get the width right.
602
-
603
- var crossColor = canvasElement.getStyle('color');
604
- if ( ! crossColor || crossColor == 'transparent') crossColor = 'white';
605
-
606
- var backgroundColor = canvasElement.getStyle('backgroundColor');
607
- if ( ! backgroundColor || backgroundColor == 'transparent') backgroundColor = 'rgba(0, 0, 0, 0.2)';
608
- canvasElement.setStyle({backgroundColor: 'transparent'});
609
-
610
- canvasElement.width = size;
611
- canvasElement.height = size;
612
-
613
- var ctx = canvasElement.getContext('2d');
614
-
615
- ctx.clearRect (0, 0, size, size);
616
-
617
- ctx.beginPath();
618
-
619
- var padding = size / 2.95;
620
- ctx.fillStyle = backgroundColor;
621
- ctx.lineWidth = size / 5.26;
622
- ctx.strokeStyle = crossColor;
623
- ctx.lineCap = 'round';
624
-
625
- ctx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2, false);
626
- ctx.fill();
627
-
628
- ctx.beginPath();
629
- ctx.moveTo(padding, padding);
630
- ctx.lineTo(size - padding, size - padding);
631
- ctx.stroke();
632
-
633
- ctx.beginPath();
634
- ctx.moveTo(size - padding, padding);
635
- ctx.lineTo(padding, size - padding);
636
- ctx.stroke();
637
-
638
- },
639
- /**
640
- * Sets the content of the tooltip.
641
- * This can be a function or a string. The function will be executed, and the
642
- * result used as new content of the tooltip.
643
- *
644
- * If the tooltip is visible, this function calls updateElementContent()
645
- **/
646
- setContent: function(content) {
647
- this.content = content;
648
- if (this.visible) this.updateElementContent();
649
- },
650
- /**
651
- * Actually updates the html element with the content.
652
- * This function also evaluates the content function, if content is a function.
653
- **/
654
- updateElementContent: function() {
655
- var contentDiv = this.container.down('.content');
656
- if (contentDiv) {
657
-
658
- if (Object.isFunction(this.content)) {
659
- this.debug('Executing content function.');
660
- this.content = this.content(this);
661
- }
662
-
663
- contentDiv.update(this.options.escapeHtml ? this.content.escapeHTML() : this.content);
664
- }
665
- this.storeAndFixDimensions();
666
- },
667
- storeAndFixDimensions: function() {
668
- this.container.setStyle({width: 'auto', left: '0px', top: '0px'});
669
- this.dimensions = this.container.getDimensions();
670
- this.container.setStyle({width: this.dimensions.width + 'px', left: this.lastPosition.left + 'px', top: this.lastPosition.top + 'px'});
671
- },
672
- destroyAllElements: function() {if (this.container) this.container.remove();},
673
- clearShowTimeout: function() {window.clearTimeout(this.timeoutId);},
674
- clearHideTimeout: function() {window.clearTimeout(this.hideTimeoutId);},
675
- clearTimeouts: function() {
676
- window.clearTimeout(this.visibilityStateTimeoutId);
677
- this.clearShowTimeout();
678
- this.clearHideTimeout();
679
- },
680
- /** Gets called only when doShow() is called, not when show() is called **/
681
- setupObserversForReallyVisibleTip: function() {
682
- this.options.showTriggerElementsWhenVisible.each(function(pair) {$(pair.element).observe(pair.event, this.bound.show);}, this);
683
- },
684
- /** Gets only called when show() is called. show() might not really result in showing the tooltip, because there may
685
- be another trigger that calls hide() directly after. **/
686
- setupObserversForVisibleTip: function() {
687
- this.options.hideTriggerElements.each(function(pair) {$(pair.element).observe(pair.event, this.bound.hide);}, this);
688
- this.options.showTriggerElementsWhenHidden.each(function(pair) {$(pair.element).stopObserving(pair.event, this.bound.show);}, this);
689
- Event.observe(document.onresize ? document : window, "resize", this.bound.position);
690
- Event.observe(window, "scroll", this.bound.position);
691
- },
692
- /** Gets called only when doHide() is called. */
693
- setupObserversForReallyHiddenTip: function() {
694
- this.options.showTriggerElementsWhenVisible.each(function(pair) {$(pair.element).stopObserving(pair.event, this.bound.show);}, this);
695
- },
696
- /** Gets called everytime hide() is called. See setupObserversForVisibleTip for more info **/
697
- setupObserversForHiddenTip: function() {
698
- this.options.showTriggerElementsWhenHidden.each(function(pair) {$(pair.element).observe(pair.event, this.bound.show);}, this);
699
- this.options.hideTriggerElements.each(function(pair) {$(pair.element).stopObserving(pair.event, this.bound.hide);}, this);
700
- Event.stopObserving(document.onresize ? document : window, "resize", this.bound.position);
701
- Event.stopObserving(window, "scroll", this.bound.position);
702
- },
703
- /**
704
- * The show function only schedules the tooltip to show. (If there is a delay, this function will generate the timer)
705
- * The actual function to show the tooltip is doShow().
706
- **/
707
- show: function(evt) {
708
- this.abortHiding();
709
- if (this.visible) return;
710
-
711
- this.debug('Showing in ' + this.options.delay + 's.');
712
-
713
- if (this.options.group) Tips.abortShowingGroup(this.options.group);
714
-
715
- this.waitingToShow = true;
716
-
717
- // Even though it is not yet visible, I already attach the observers, so the tooltip won't show if a hideEvent is triggered.
718
- this.setupObserversForVisibleTip();
719
-
720
- // So the tooltip is positioned as soon as it shows.
721
- this.followMousePosition();
722
- this.position(evt);
723
-
724
- if (!this.options.delay) this.bound.doShow(evt);
725
- else this.timeoutId = this.bound.doShow.delay(this.options.delay);
726
- },
727
- // If the tip is waiting to show (and only then), this will abort it.
728
- abortShowing: function() {
729
- if (this.waitingToShow) {
730
- this.debug('Aborting showing.');
731
- this.clearTimeouts();
732
- this.stopFollowingMousePosition();
733
- this.waitingToShow = false;
734
- this.setupObserversForHiddenTip();
735
- }
736
- },
737
- /**
738
- * Actually shows the tooltip. This function is called when any possible delay has expired.
739
- **/
740
- doShow: function() {
741
- this.clearTimeouts();
742
- if (this.visible) return;
743
-
744
- // Thanks to Torsten Saam for this enhancement.
745
- if ( ! this.triggerElementExists()) { this.deactivate(); return; }
746
-
747
- this.debug('Showing!');
748
-
749
- if (this.options.group) Tips.hideGroup(this.options.group);
750
-
751
-
752
- this.visible = true;
753
- this.waitingToShow = false;
754
-
755
- if (!this.tooltipElement) this.buildElements();
756
- this.updateElementContent();
757
-
758
- if (this.options.ajax && !this.loaded) {this.loadAjax();}
759
-
760
- this.searchAndActivateHideButtons();
761
-
762
- this.ensureElement();
763
- this.container.setStyle({zIndex: Opentip.lastZIndex += 1});
764
-
765
- // The order is important here! Do not reverse.
766
- this.setupObserversForReallyVisibleTip();
767
- this.setupObserversForVisibleTip();
768
-
769
- if (Opentip.useScriptaculousTransitions) {
770
- if (this.options.showEffect || this.options.hideEffect) this.cancelEffects();
771
-
772
- if (!this.options.showEffect || !this.container[this.options.showEffect]) this.container.show();
773
- else this.container[this.options.showEffect]({duration: this.options.showEffectDuration, queue: this.queue, afterFinish: this.afterShowEffect.bind(this)});
774
- if (Opentip.useIFrame()) this.iFrameElement.show();
775
- }
776
-
777
- this.position();
778
-
779
- this.container.removeClassName('ot-hidden').addClassName('ot-becoming-visible');
780
-
781
-
782
- /**
783
- * The next lines may seem a bit weird. I ran into some bizarre opera problems
784
- * while implementing the switch of the different states.
785
- *
786
- * This is what's happening here:
787
- *
788
- * I wanted to just remove ot-completely-hidden, and add ot-becoming-visible
789
- * (so the tip has the style it should have when it appears) and then switch
790
- * ot-becoming-visible with ot-visible so the transition can take place.
791
- * I then setup a timer to set ot-completely-visible when appropriate.
792
- *
793
- * I ran into problems with opera, which showed the tip for a frame because
794
- * apparently the -o-transforms are slower then just setting display: none
795
- * (or something...)
796
- *
797
- * So I have to 1) set ot-becoming-visible first, so the tip has the appropriate
798
- * CSS definitions set, 2) defer the removal of ot-completely-hidden, so it's
799
- * not invisible anymore, and 3) defer the rest of the process (setting ot-visible
800
- * and stuff) so the transition takes place.
801
- */
802
-
803
- var startShowEffect = function() {
804
- if (Opentip.useCss3Transitions) {
805
- this.container.setCss3Style({'transitionDuration': this.options.showEffectDuration + 's'});
806
- }
807
-
808
- this.container.removeClassName('ot-becoming-visible').addClassName('ot-visible');
809
- if (this.options.showEffect && this.options.showEffectDuration) {
810
- this.visibilityStateTimeoutId = (function() {this.removeClassName('ot-visible').addClassName('ot-completely-visible');}).bind(this.container).delay(this.options.showEffectDuration);
811
- }
812
- else {
813
- this.container.removeClassName('ot-visible').addClassName('ot-completely-visible');
814
- }
815
-
816
- this.activateFirstInput();
817
- };
818
-
819
-
820
- (function() {
821
- this.container.removeClassName('ot-completely-hidden');
822
- (startShowEffect).bind(this).defer(); // Has to be deferred, so the div has the class ot-becoming-visible.
823
- }).bind(this).defer();
824
-
825
-
826
-
827
- },
828
- loadAjax: function() {
829
- if (this.loading) return;
830
- this.loading = true;
831
- this.container.addClassName('ot-loading');
832
-
833
- this.debug('Loading content from ' + this.options.ajax.url + '.');
834
-
835
- new Ajax.Request(this.options.ajax.url,
836
- Object.extend({
837
- onComplete: function() {
838
- this.container.removeClassName('ot-loading');
839
- this.loaded = true;
840
- this.loading = false;
841
- this.updateElementContent();
842
- this.searchAndActivateHideButtons();
843
- this.activateFirstInput();
844
- this.position();
845
- }.bind(this),
846
- onSuccess: function(transport) {
847
- this.debug('Loading successfull.');
848
- this.content = transport.responseText;
849
- }.bind(this),
850
- onFailure: function() {
851
- this.debug('There was a problem downloading the file.');
852
- this.options.escapeHtml = false;
853
- this.content = '<a class="close">There was a problem downloading the content.</a>';
854
- }.bind(this)}, this.options.ajax.options || {}));
855
- },
856
- afterShowEffect: function() {
857
- this.activateFirstInput();
858
- this.position();
859
- },
860
- activateFirstInput: function() {
861
- // TODO: check if there is a simple way of finding EITHER an input OR a textarea.
862
- var input = this.container.down('input');
863
- var textarea = this.container.down('textarea');
864
- if (input) {input.focus();}
865
- else if (textarea) textarea.focus();
866
- },
867
- searchAndActivateHideButtons: function() {
868
- if (!this.options.hideTrigger || this.options.hideTrigger.include('closeButton')) {
869
- this.options.hideTriggerElements = [];
870
- this.container.select('.close').each(function(el) {
871
- this.options.hideTriggerElements.push({element: el, event: 'click'});
872
- }, this);
873
- if (this.visible) this.setupObserversForVisibleTip();
874
- }
875
- },
876
- hide: function(afterFinish) {
877
- this.abortShowing();
878
- if (!this.visible) return;
879
-
880
- this.debug('Hiding in ' + this.options.hideDelay + 's.');
881
-
882
- this.waitingToHide = true;
883
-
884
- // We start observing even though it is not yet hidden, so the tooltip does not disappear when a showEvent is triggered.
885
- this.setupObserversForHiddenTip();
886
-
887
- this.hideTimeoutId = this.bound.doHide.delay(this.options.hideDelay, afterFinish); // hide has to be delayed because when hovering children a mouseout is registered.
888
- },
889
- abortHiding: function() {
890
- if (this.waitingToHide) {
891
- this.debug('Aborting hiding.');
892
- this.clearTimeouts();
893
- this.waitingToHide = false;
894
- this.setupObserversForVisibleTip();
895
- }
896
- },
897
- doHide: function(afterFinish) {
898
- this.clearTimeouts();
899
- if (!this.visible) return;
900
-
901
- this.debug('Hiding!');
902
-
903
- this.visible = false;
904
-
905
- this.waitingToHide = false;
906
-
907
- this.deactivateElementEnsurance();
908
-
909
- // The order is important here! Do not reverse.
910
- this.setupObserversForReallyHiddenTip();
911
- this.setupObserversForHiddenTip();
912
-
913
- if (!this.options.fixed) this.stopFollowingMousePosition();
914
-
915
- if (Opentip.useScriptaculousTransitions) {
916
- if (this.options.showEffect || this.options.hideEffect) this.cancelEffects();
917
-
918
- if (!this.options.hideEffect || !this.container[this.options.hideEffect]) this.container.hide();
919
- else {
920
- var effectOptions = {duration: this.options.hideEffectDuration, queue: this.queue};
921
- if(afterFinish && Object.isFunction(afterFinish)) effectOptions.afterFinish = afterFinish;
922
- this.container[this.options.hideEffect](effectOptions);
923
- }
924
- if (Opentip.useIFrame()) this.iFrameElement.hide();
925
- }
926
-
927
- if (Opentip.useCss3Transitions) {
928
- this.container.setCss3Style({'transitionDuration': this.options.hideEffectDuration + 's'});
929
- }
930
-
931
- this.container.removeClassName('ot-visible').removeClassName('ot-completely-visible').addClassName('ot-hidden');
932
- if (this.options.hideEffect && this.options.hideEffectDuration) {
933
- this.visibilityStateTimeoutId = (function() {
934
- this.setCss3Style({'transitionDuration': '0s'});
935
- this.removeClassName('ot-hidden').addClassName('ot-completely-hidden');
936
- }).bind(this.container).delay(this.options.showEffectDuration);
937
- }
938
- else {
939
- this.container.removeClassName('ot-hidden').addClassName('ot-completely-hidden');
940
- }
941
-
942
- },
943
- cancelEffects: function() {Effect.Queues.get(this.queue.scope).invoke('cancel');},
944
- followMousePosition: function() {if (!this.options.fixed) $(document.body).observe('mousemove', this.bound.position);},
945
- stopFollowingMousePosition: function() {if (!this.options.fixed) $(document.body).stopObserving('mousemove', this.bound.position);},
946
- positionsEqual: function(position1, position2) {
947
- return (position1.left == position2.left && position1.top == position2.top);
948
- },
949
- position: function(evt) {
950
- var evt = evt || this.lastEvt;
951
-
952
- this.currentStemPosition = this.options.stem; // This gets reset by ensureViewportContainment if necessary.
953
- var position = this.ensureViewportContainment(evt, this.getPosition(evt));
954
- if (this.positionsEqual(position, this.lastPosition)) {
955
- this.positionStem();
956
- return;
957
- }
958
-
959
- this.lastPosition = position;
960
- if (position) {
961
- var style = {'left': position.left + 'px', 'top': position.top + 'px'};
962
- this.container.setStyle(style);
963
- if (Opentip.useIFrame() && this.iFrameElement) {
964
- this.iFrameElement.setStyle({width: this.container.getWidth() + 'px', height: this.container.getHeight() + 'px'});
965
- }
966
-
967
- /**
968
- * Following is a redraw fix, because I noticed some drawing errors in some browsers when tooltips where overlapping.
969
- */
970
- var container = this.container;
971
- (function() {
972
- container.style.visibility = "hidden"; // I chose visibility instead of display so that I don't interfere with appear/disappear effects.
973
- var redrawFix = container.offsetHeight;
974
- container.style.visibility = "visible";
975
- }).defer();
976
- }
977
- this.positionStem();
978
- },
979
- getPosition: function(evt, tipJ, trgJ, stem) {
980
- var tipJ = tipJ || this.options.tipJoint;
981
- var trgJ = trgJ || this.options.targetJoint;
982
-
983
- var position = {};
984
-
985
- if (this.options.target) {
986
- var tmp = this.options.target.cumulativeOffset();
987
- position.left = tmp[0];
988
- position.top = tmp[1];
989
- if (trgJ[0] == 'right') {
990
- // For wrapping inline elements, left + width does not give the right border, because left is where
991
- // the element started, not its most left position.
992
- if (typeof this.options.target.getBoundingClientRect != 'undefined') {
993
- position.left = this.options.target.getBoundingClientRect().right + $(document.viewport).getScrollOffsets().left;
994
- }
995
- else {
996
- position.left = position.left + this.options.target.getWidth();
997
- }
998
- }
999
- else if (trgJ[0] == 'center') {position.left += Math.round(this.options.target.getWidth() / 2);}
1000
- if (trgJ[1] == 'bottom') {position.top += this.options.target.getHeight();}
1001
- else if (trgJ[1] == 'middle') {position.top += Math.round(this.options.target.getHeight() / 2);}
1002
- } else {
1003
- if (!evt) return; // No event passed, so returning.
1004
- this.lastEvt = evt;
1005
- position.left = Event.pointerX(evt);
1006
- position.top = Event.pointerY(evt);
1007
- }
1008
-
1009
- if (this.options.autoOffset) {
1010
- var stemSize = this.options.stem ? this.options.stemSize : 0;
1011
- var offsetDistance = (stemSize && this.options.fixed) ? 2 : 10; // If there is as stem offsets dont need to be that big if fixed.
1012
- var additionalHorizontal = (tipJ[1] == 'middle' && !this.options.fixed) ? 15 : 0;
1013
- var additionalVertical = (tipJ[0] == 'center' && !this.options.fixed) ? 15 : 0;
1014
- if (tipJ[0] == 'right') position.left -= offsetDistance + additionalHorizontal;
1015
- else if (tipJ[0] == 'left') position.left += offsetDistance + additionalHorizontal;
1016
- if (tipJ[1] == 'bottom') position.top -= offsetDistance + additionalVertical;
1017
- else if (tipJ[1] == 'top') position.top += offsetDistance + additionalVertical;
1018
-
1019
- if (stemSize) {
1020
- var stem = stem || this.options.stem;
1021
- if (stem[0] == 'right') position.left -= stemSize;
1022
- else if (stem[0] == 'left') position.left += stemSize;
1023
- if (stem[1] == 'bottom') position.top -= stemSize;
1024
- else if (stem[1] == 'top') position.top += stemSize;
1025
- }
1026
- }
1027
- position.left += this.options.offset[0];
1028
- position.top += this.options.offset[1];
1029
-
1030
- if (tipJ[0] == 'right') {position.left -= this.container.getWidth();}
1031
- if (tipJ[0] == 'center') {position.left -= Math.round(this.container.getWidth()/2);}
1032
- if (tipJ[1] == 'bottom') {position.top -= this.container.getHeight();}
1033
- if (tipJ[1] == 'middle') {position.top -= Math.round(this.container.getHeight()/2);}
1034
-
1035
- return position;
1036
- },
1037
- ensureViewportContainment: function(evt, position) {
1038
- // Sometimes the element is theoretically visible, but an effect is not yet showing it.
1039
- // So the calculation of the offsets is incorrect sometimes, which results in faulty repositioning.
1040
- if (!this.visible) return position;
1041
-
1042
- var sticksOut = [ this.sticksOutX(position), this.sticksOutY(position) ];
1043
- if (!sticksOut[0] && !sticksOut[1]) return position;
1044
-
1045
- var tipJ = this.options.tipJoint.clone();
1046
- var trgJ = this.options.targetJoint.clone();
1047
-
1048
- var viewportScrollOffset = $(document.viewport).getScrollOffsets();
1049
- var dimensions = this.dimensions;
1050
- var viewportOffset = {left: position.left - viewportScrollOffset.left, top: position.top - viewportScrollOffset.top};
1051
- var viewportDimensions = document.viewport.getDimensions();
1052
- var reposition = false;
1053
-
1054
- if (viewportDimensions.width >= dimensions.width) {
1055
- if (viewportOffset.left < 0) {
1056
- reposition = true;
1057
- tipJ[0] = 'left';
1058
- if (this.options.target && trgJ[0] == 'left') {trgJ[0] = 'right';}
1059
- }
1060
- else if (viewportOffset.left + dimensions.width > viewportDimensions.width) {
1061
- reposition = true;
1062
- tipJ[0] = 'right';
1063
- if (this.options.target && trgJ[0] == 'right') {trgJ[0] = 'left';}
1064
- }
1065
- }
1066
-
1067
- if (viewportDimensions.height >= dimensions.height) {
1068
- if (viewportOffset.top < 0) {
1069
- reposition = true;
1070
- tipJ[1] = 'top';
1071
- if (this.options.target && trgJ[1] == 'top') {trgJ[1] = 'bottom';}
1072
- }
1073
- else if (viewportOffset.top + dimensions.height > viewportDimensions.height) {
1074
- reposition = true;
1075
- tipJ[1] = 'bottom';
1076
- if (this.options.target && trgJ[1] == 'bottom') {trgJ[1] = 'top';}
1077
- }
1078
- }
1079
- if (reposition) {
1080
- var newPosition = this.getPosition(evt, tipJ, trgJ, tipJ);
1081
- var newSticksOut = [ this.sticksOutX(newPosition), this.sticksOutY(newPosition) ];
1082
- var revertedCount = 0;
1083
- for (var i = 0; i <=1; i ++) {
1084
- if (newSticksOut[i] && newSticksOut[i] != sticksOut[i]) {
1085
- // The tooltip changed sides, but now is sticking out the other side of the window.
1086
- // If its still sticking out, but on the same side, it's ok. At least, it sticks out less.
1087
- revertedCount ++;
1088
- tipJ[i] = this.options.tipJoint[i];
1089
- if (this.options.target) {trgJ[i] = this.options.targetJoint[i];}
1090
- }
1091
- }
1092
- if (revertedCount < 2) {
1093
- this.currentStemPosition = tipJ;
1094
- return this.getPosition(evt, tipJ, trgJ, tipJ);
1095
- }
1096
- }
1097
- return position;
1098
- },
1099
- sticksOut: function(position) {
1100
- return this.sticksOutX(position) || this.sticksOutY(position);
1101
- },
1102
- /**
1103
- * return 1 for left 2 for right
1104
- */
1105
- sticksOutX: function(position) {
1106
- var viewportScrollOffset = $(document.viewport).getScrollOffsets();
1107
- var viewportOffset = {left: position.left - viewportScrollOffset.left, top: position.top - viewportScrollOffset.top};
1108
- if (viewportOffset.left < 0) return Opentip.STICKS_OUT_LEFT;
1109
- if (viewportOffset.left + this.dimensions.width > document.viewport.getDimensions().width) {return Opentip.STICKS_OUT_RIGHT;}
1110
- },
1111
- /**
1112
- * return 1 for top 2 for bottom
1113
- */
1114
- sticksOutY: function(position) {
1115
- var viewportScrollOffset = $(document.viewport).getScrollOffsets();
1116
- var viewportOffset = {left: position.left - viewportScrollOffset.left, top: position.top - viewportScrollOffset.top};
1117
- if (viewportOffset.top < 0) return Opentip.STICKS_OUT_TOP;
1118
- if (viewportOffset.top + this.dimensions.height > document.viewport.getDimensions().height) return Opentip.STICKS_OUT_BOTTOM;
1119
- },
1120
- getStemCanvas: function() {
1121
- return this.container.down('.stem');
1122
- },
1123
- stemPositionsEqual: function(position1, position2) {
1124
- return (position1 && position2 && position1[0] == position2[0] && position1[1] == position2[1]);
1125
- },
1126
- positionStem: function() {
1127
- // Position stem
1128
- if (this.options.stem) {
1129
-
1130
- var canvasElement = this.getStemCanvas();
1131
-
1132
- if (canvasElement && !this.stemPositionsEqual(this.lastStemPosition, this.currentStemPosition)) {
1133
-
1134
- this.debug('Setting stem style');
1135
-
1136
- this.lastStemPosition = this.currentStemPosition;
1137
-
1138
- var stemPosition = Opentip.sanitizePosition(this.currentStemPosition);
1139
- var stemSize = this.options.stemSize;
1140
-
1141
- var rotationRad = stemPosition * Math.PI / 4; // Every number means 45deg
1142
-
1143
- var baseThikness = Math.round(stemSize * 1.5);
1144
-
1145
- var realDim = {w: baseThikness, h: stemSize};
1146
-
1147
- var isCorner = false;
1148
- if (stemPosition % 2 == 1) {
1149
- // Corner
1150
- isCorner = true;
1151
- var additionalWidth = Math.round(0.707106781 * baseThikness); // 0.707106781 == sqrt(2) / 2 to calculate the adjacent leg of the triangle
1152
- realDim = {w: stemSize + additionalWidth, h: stemSize + additionalWidth};
1153
- }
1154
-
1155
- var drawDim = Object.clone(realDim); // The drawDim is so that I can draw without takin the rotation into calculation
1156
-
1157
- if (stemPosition == Opentip.position.left || stemPosition == Opentip.position.right) {
1158
- // The canvas has to be rotated
1159
- realDim.h = drawDim.w;
1160
- realDim.w = drawDim.h;
1161
- }
1162
-
1163
-
1164
- var stemColor = canvasElement.getStyle('color') || 'black';
1165
-
1166
-
1167
- canvasElement.width = realDim.w;
1168
- canvasElement.height = realDim.h;
1169
-
1170
- // Now draw the stem.
1171
- var ctx = canvasElement.getContext('2d');
1172
-
1173
- ctx.clearRect (0, 0, canvasElement.width, canvasElement.height);
1174
- ctx.beginPath();
1175
-
1176
- ctx.fillStyle = stemColor;
1177
-
1178
- ctx.save();
1179
-
1180
- ctx.translate(realDim.w / 2, realDim.h / 2);
1181
- var rotations = Math.floor(stemPosition / 2);
1182
- ctx.rotate(rotations * Math.PI / 2);
1183
- if (realDim.w == drawDim.w) { // This is a real hack because I don't know how to reset to 0,0
1184
- ctx.translate(-realDim.w / 2, -realDim.h / 2);
1185
- }
1186
- else {
1187
- ctx.translate(-realDim.h / 2, -realDim.w / 2);
1188
- }
1189
-
1190
- if (isCorner) {
1191
- ctx.moveTo(additionalWidth, drawDim.h);
1192
- ctx.lineTo(drawDim.w, 0);
1193
- ctx.lineTo(0, drawDim.h - additionalWidth);
1194
- }
1195
- else {
1196
- ctx.moveTo(drawDim.w / 2 - baseThikness / 2, drawDim.h);
1197
- ctx.lineTo(drawDim.w / 2, 0);
1198
- ctx.lineTo(drawDim.w / 2 + baseThikness / 2, drawDim.h);
1199
- }
1200
- ctx.fill();
1201
- ctx.restore();
1202
-
1203
-
1204
- var style = {width: realDim.w + 'px', height: realDim.h + 'px', left: '', right: '', top: '', bottom: ''};
1205
-
1206
- switch (stemPosition) {
1207
- case Opentip.position.top:
1208
- style.top = - realDim.h + 'px';
1209
- style.left = - Math.round(realDim.w / 2) + 'px';
1210
- break;
1211
- case Opentip.position.right:
1212
- style.top = - Math.round(realDim.h / 2) + 'px';
1213
- style.left = 0;
1214
- break;
1215
- case Opentip.position.bottom:
1216
- style.top = 0;
1217
- style.left = - Math.round(realDim.w / 2) + 'px';
1218
- break;
1219
- case Opentip.position.left:
1220
- style.top = - Math.round(realDim.h / 2) + 'px';
1221
- style.left = - realDim.w + 'px';
1222
- break;
1223
- case Opentip.position.topRight:
1224
- style.top = - stemSize + 'px';
1225
- style.left = - additionalWidth + 'px';
1226
- break;
1227
- case Opentip.position.bottomRight:
1228
- style.top = - additionalWidth + 'px';
1229
- style.left = - additionalWidth + 'px';
1230
- break;
1231
- case Opentip.position.bottomLeft:
1232
- style.top = - additionalWidth + 'px';
1233
- style.left = - stemSize + 'px';
1234
- break;
1235
- case Opentip.position.topLeft:
1236
- style.top = - stemSize + 'px';
1237
- style.left = - stemSize + 'px';
1238
- break;
1239
- default:
1240
- throw 'Unknown stem position: ' + stemPosition;
1241
- }
1242
-
1243
- canvasElement.setStyle(style);
1244
-
1245
- var stemContainer = canvasElement.up('.stem-container');
1246
- stemContainer.removeClassName('left').removeClassName('right').removeClassName('center').removeClassName('top').removeClassName('bottom').removeClassName('middle');
1247
-
1248
- switch (stemPosition) {
1249
- case Opentip.position.top: case Opentip.position.topLeft: case Opentip.position.topRight:
1250
- stemContainer.addClassName('top');
1251
- break;
1252
- case Opentip.position.bottom: case Opentip.position.bottomLeft: case Opentip.position.bottomRight:
1253
- stemContainer.addClassName('bottom');
1254
- break;
1255
- default:
1256
- stemContainer.addClassName('middle');
1257
- break;
1258
- }
1259
- switch (stemPosition) {
1260
- case Opentip.position.left: case Opentip.position.topLeft: case Opentip.position.bottomLeft:
1261
- stemContainer.addClassName('left');
1262
- break;
1263
- case Opentip.position.right: case Opentip.position.topRight: case Opentip.position.bottomRight:
1264
- stemContainer.addClassName('right');
1265
- break;
1266
- default:
1267
- stemContainer.addClassName('center');
1268
- break;
1269
- }
1270
-
1271
- }
1272
-
1273
- }
1274
- },
1275
- triggerElementExists: function(element) {
1276
- return this.triggerElement.parentNode && this.triggerElement.visible() && this.triggerElement.descendantOf(document.body);
1277
- },
1278
- ensureElementInterval: 1000, // In milliseconds, how often opentip should check for the existance of the element
1279
- ensureElement: function() { // Regularely checks if the element is still in the dom.
1280
- this.deactivateElementEnsurance();
1281
- if ( ! this.triggerElementExists()) {this.deactivate();}
1282
- this.ensureElementTimeoutId = setTimeout(this.ensureElement.bind(this), this.ensureElementInterval);
1283
- },
1284
- deactivateElementEnsurance: function() {clearTimeout(this.ensureElementTimeoutId);}
1285
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/prototype.js DELETED
@@ -1,6081 +0,0 @@
1
- /* Prototype JavaScript framework, version 1.7
2
- * (c) 2005-2010 Sam Stephenson
3
- *
4
- * Prototype is freely distributable under the terms of an MIT-style license.
5
- * For details, see the Prototype web site: http://www.prototypejs.org/
6
- *
7
- *--------------------------------------------------------------------------*/
8
-
9
- var Prototype = {
10
-
11
- Version: '1.7',
12
-
13
- Browser: (function(){
14
- var ua = navigator.userAgent;
15
- var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
16
- return {
17
- IE: !!window.attachEvent && !isOpera,
18
- Opera: isOpera,
19
- WebKit: ua.indexOf('AppleWebKit/') > -1,
20
- Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
21
- MobileSafari: /Apple.*Mobile/.test(ua)
22
- }
23
- })(),
24
-
25
- BrowserFeatures: {
26
- XPath: !!document.evaluate,
27
-
28
- SelectorsAPI: !!document.querySelector,
29
-
30
- ElementExtensions: (function() {
31
- var constructor = window.Element || window.HTMLElement;
32
- return !!(constructor && constructor.prototype);
33
- })(),
34
- SpecificElementExtensions: (function() {
35
- if (typeof window.HTMLDivElement !== 'undefined')
36
- return true;
37
-
38
- var div = document.createElement('div'),
39
- form = document.createElement('form'),
40
- isSupported = false;
41
-
42
- if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
43
- isSupported = true;
44
- }
45
-
46
- div = form = null;
47
-
48
- return isSupported;
49
- })()
50
- },
51
-
52
- ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
53
- JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
54
-
55
- emptyFunction: function() { },
56
-
57
- K: function(x) { return x }
58
- };
59
-
60
- if (Prototype.Browser.MobileSafari)
61
- Prototype.BrowserFeatures.SpecificElementExtensions = false;
62
- /* Based on Alex Arnell's inheritance implementation. */
63
-
64
- var Class = (function() {
65
-
66
- var IS_DONTENUM_BUGGY = (function(){
67
- for (var p in { toString: 1 }) {
68
- if (p === 'toString') return false;
69
- }
70
- return true;
71
- })();
72
-
73
- function subclass() {};
74
- function create() {
75
- var parent = null, properties = $A(arguments);
76
- if (Object.isFunction(properties[0]))
77
- parent = properties.shift();
78
-
79
- function klass() {
80
- this.initialize.apply(this, arguments);
81
- }
82
-
83
- Object.extend(klass, Class.Methods);
84
- klass.superclass = parent;
85
- klass.subclasses = [];
86
-
87
- if (parent) {
88
- subclass.prototype = parent.prototype;
89
- klass.prototype = new subclass;
90
- parent.subclasses.push(klass);
91
- }
92
-
93
- for (var i = 0, length = properties.length; i < length; i++)
94
- klass.addMethods(properties[i]);
95
-
96
- if (!klass.prototype.initialize)
97
- klass.prototype.initialize = Prototype.emptyFunction;
98
-
99
- klass.prototype.constructor = klass;
100
- return klass;
101
- }
102
-
103
- function addMethods(source) {
104
- var ancestor = this.superclass && this.superclass.prototype,
105
- properties = Object.keys(source);
106
-
107
- if (IS_DONTENUM_BUGGY) {
108
- if (source.toString != Object.prototype.toString)
109
- properties.push("toString");
110
- if (source.valueOf != Object.prototype.valueOf)
111
- properties.push("valueOf");
112
- }
113
-
114
- for (var i = 0, length = properties.length; i < length; i++) {
115
- var property = properties[i], value = source[property];
116
- if (ancestor && Object.isFunction(value) &&
117
- value.argumentNames()[0] == "$super") {
118
- var method = value;
119
- value = (function(m) {
120
- return function() { return ancestor[m].apply(this, arguments); };
121
- })(property).wrap(method);
122
-
123
- value.valueOf = method.valueOf.bind(method);
124
- value.toString = method.toString.bind(method);
125
- }
126
- this.prototype[property] = value;
127
- }
128
-
129
- return this;
130
- }
131
-
132
- return {
133
- create: create,
134
- Methods: {
135
- addMethods: addMethods
136
- }
137
- };
138
- })();
139
- (function() {
140
-
141
- var _toString = Object.prototype.toString,
142
- NULL_TYPE = 'Null',
143
- UNDEFINED_TYPE = 'Undefined',
144
- BOOLEAN_TYPE = 'Boolean',
145
- NUMBER_TYPE = 'Number',
146
- STRING_TYPE = 'String',
147
- OBJECT_TYPE = 'Object',
148
- FUNCTION_CLASS = '[object Function]',
149
- BOOLEAN_CLASS = '[object Boolean]',
150
- NUMBER_CLASS = '[object Number]',
151
- STRING_CLASS = '[object String]',
152
- ARRAY_CLASS = '[object Array]',
153
- DATE_CLASS = '[object Date]',
154
- NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
155
- typeof JSON.stringify === 'function' &&
156
- JSON.stringify(0) === '0' &&
157
- typeof JSON.stringify(Prototype.K) === 'undefined';
158
-
159
- function Type(o) {
160
- switch(o) {
161
- case null: return NULL_TYPE;
162
- case (void 0): return UNDEFINED_TYPE;
163
- }
164
- var type = typeof o;
165
- switch(type) {
166
- case 'boolean': return BOOLEAN_TYPE;
167
- case 'number': return NUMBER_TYPE;
168
- case 'string': return STRING_TYPE;
169
- }
170
- return OBJECT_TYPE;
171
- }
172
-
173
- function extend(destination, source) {
174
- for (var property in source)
175
- destination[property] = source[property];
176
- return destination;
177
- }
178
-
179
- function inspect(object) {
180
- try {
181
- if (isUndefined(object)) return 'undefined';
182
- if (object === null) return 'null';
183
- return object.inspect ? object.inspect() : String(object);
184
- } catch (e) {
185
- if (e instanceof RangeError) return '...';
186
- throw e;
187
- }
188
- }
189
-
190
- function toJSON(value) {
191
- return Str('', { '': value }, []);
192
- }
193
-
194
- function Str(key, holder, stack) {
195
- var value = holder[key],
196
- type = typeof value;
197
-
198
- if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
199
- value = value.toJSON(key);
200
- }
201
-
202
- var _class = _toString.call(value);
203
-
204
- switch (_class) {
205
- case NUMBER_CLASS:
206
- case BOOLEAN_CLASS:
207
- case STRING_CLASS:
208
- value = value.valueOf();
209
- }
210
-
211
- switch (value) {
212
- case null: return 'null';
213
- case true: return 'true';
214
- case false: return 'false';
215
- }
216
-
217
- type = typeof value;
218
- switch (type) {
219
- case 'string':
220
- return value.inspect(true);
221
- case 'number':
222
- return isFinite(value) ? String(value) : 'null';
223
- case 'object':
224
-
225
- for (var i = 0, length = stack.length; i < length; i++) {
226
- if (stack[i] === value) { throw new TypeError(); }
227
- }
228
- stack.push(value);
229
-
230
- var partial = [];
231
- if (_class === ARRAY_CLASS) {
232
- for (var i = 0, length = value.length; i < length; i++) {
233
- var str = Str(i, value, stack);
234
- partial.push(typeof str === 'undefined' ? 'null' : str);
235
- }
236
- partial = '[' + partial.join(',') + ']';
237
- } else {
238
- var keys = Object.keys(value);
239
- for (var i = 0, length = keys.length; i < length; i++) {
240
- var key = keys[i], str = Str(key, value, stack);
241
- if (typeof str !== "undefined") {
242
- partial.push(key.inspect(true)+ ':' + str);
243
- }
244
- }
245
- partial = '{' + partial.join(',') + '}';
246
- }
247
- stack.pop();
248
- return partial;
249
- }
250
- }
251
-
252
- function stringify(object) {
253
- return JSON.stringify(object);
254
- }
255
-
256
- function toQueryString(object) {
257
- return $H(object).toQueryString();
258
- }
259
-
260
- function toHTML(object) {
261
- return object && object.toHTML ? object.toHTML() : String.interpret(object);
262
- }
263
-
264
- function keys(object) {
265
- if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
266
- var results = [];
267
- for (var property in object) {
268
- if (object.hasOwnProperty(property)) {
269
- results.push(property);
270
- }
271
- }
272
- return results;
273
- }
274
-
275
- function values(object) {
276
- var results = [];
277
- for (var property in object)
278
- results.push(object[property]);
279
- return results;
280
- }
281
-
282
- function clone(object) {
283
- return extend({ }, object);
284
- }
285
-
286
- function isElement(object) {
287
- return !!(object && object.nodeType == 1);
288
- }
289
-
290
- function isArray(object) {
291
- return _toString.call(object) === ARRAY_CLASS;
292
- }
293
-
294
- var hasNativeIsArray = (typeof Array.isArray == 'function')
295
- && Array.isArray([]) && !Array.isArray({});
296
-
297
- if (hasNativeIsArray) {
298
- isArray = Array.isArray;
299
- }
300
-
301
- function isHash(object) {
302
- return object instanceof Hash;
303
- }
304
-
305
- function isFunction(object) {
306
- return _toString.call(object) === FUNCTION_CLASS;
307
- }
308
-
309
- function isString(object) {
310
- return _toString.call(object) === STRING_CLASS;
311
- }
312
-
313
- function isNumber(object) {
314
- return _toString.call(object) === NUMBER_CLASS;
315
- }
316
-
317
- function isDate(object) {
318
- return _toString.call(object) === DATE_CLASS;
319
- }
320
-
321
- function isUndefined(object) {
322
- return typeof object === "undefined";
323
- }
324
-
325
- extend(Object, {
326
- extend: extend,
327
- inspect: inspect,
328
- toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
329
- toQueryString: toQueryString,
330
- toHTML: toHTML,
331
- keys: Object.keys || keys,
332
- values: values,
333
- clone: clone,
334
- isElement: isElement,
335
- isArray: isArray,
336
- isHash: isHash,
337
- isFunction: isFunction,
338
- isString: isString,
339
- isNumber: isNumber,
340
- isDate: isDate,
341
- isUndefined: isUndefined
342
- });
343
- })();
344
- Object.extend(Function.prototype, (function() {
345
- var slice = Array.prototype.slice;
346
-
347
- function update(array, args) {
348
- var arrayLength = array.length, length = args.length;
349
- while (length--) array[arrayLength + length] = args[length];
350
- return array;
351
- }
352
-
353
- function merge(array, args) {
354
- array = slice.call(array, 0);
355
- return update(array, args);
356
- }
357
-
358
- function argumentNames() {
359
- var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
360
- .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
361
- .replace(/\s+/g, '').split(',');
362
- return names.length == 1 && !names[0] ? [] : names;
363
- }
364
-
365
- function bind(context) {
366
- if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
367
- var __method = this, args = slice.call(arguments, 1);
368
- return function() {
369
- var a = merge(args, arguments);
370
- return __method.apply(context, a);
371
- }
372
- }
373
-
374
- function bindAsEventListener(context) {
375
- var __method = this, args = slice.call(arguments, 1);
376
- return function(event) {
377
- var a = update([event || window.event], args);
378
- return __method.apply(context, a);
379
- }
380
- }
381
-
382
- function curry() {
383
- if (!arguments.length) return this;
384
- var __method = this, args = slice.call(arguments, 0);
385
- return function() {
386
- var a = merge(args, arguments);
387
- return __method.apply(this, a);
388
- }
389
- }
390
-
391
- function delay(timeout) {
392
- var __method = this, args = slice.call(arguments, 1);
393
- timeout = timeout * 1000;
394
- return window.setTimeout(function() {
395
- return __method.apply(__method, args);
396
- }, timeout);
397
- }
398
-
399
- function defer() {
400
- var args = update([0.01], arguments);
401
- return this.delay.apply(this, args);
402
- }
403
-
404
- function wrap(wrapper) {
405
- var __method = this;
406
- return function() {
407
- var a = update([__method.bind(this)], arguments);
408
- return wrapper.apply(this, a);
409
- }
410
- }
411
-
412
- function methodize() {
413
- if (this._methodized) return this._methodized;
414
- var __method = this;
415
- return this._methodized = function() {
416
- var a = update([this], arguments);
417
- return __method.apply(null, a);
418
- };
419
- }
420
-
421
- return {
422
- argumentNames: argumentNames,
423
- bind: bind,
424
- bindAsEventListener: bindAsEventListener,
425
- curry: curry,
426
- delay: delay,
427
- defer: defer,
428
- wrap: wrap,
429
- methodize: methodize
430
- }
431
- })());
432
-
433
-
434
-
435
- (function(proto) {
436
-
437
-
438
- function toISOString() {
439
- return this.getUTCFullYear() + '-' +
440
- (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
441
- this.getUTCDate().toPaddedString(2) + 'T' +
442
- this.getUTCHours().toPaddedString(2) + ':' +
443
- this.getUTCMinutes().toPaddedString(2) + ':' +
444
- this.getUTCSeconds().toPaddedString(2) + 'Z';
445
- }
446
-
447
-
448
- function toJSON() {
449
- return this.toISOString();
450
- }
451
-
452
- if (!proto.toISOString) proto.toISOString = toISOString;
453
- if (!proto.toJSON) proto.toJSON = toJSON;
454
-
455
- })(Date.prototype);
456
-
457
-
458
- RegExp.prototype.match = RegExp.prototype.test;
459
-
460
- RegExp.escape = function(str) {
461
- return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
462
- };
463
- var PeriodicalExecuter = Class.create({
464
- initialize: function(callback, frequency) {
465
- this.callback = callback;
466
- this.frequency = frequency;
467
- this.currentlyExecuting = false;
468
-
469
- this.registerCallback();
470
- },
471
-
472
- registerCallback: function() {
473
- this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
474
- },
475
-
476
- execute: function() {
477
- this.callback(this);
478
- },
479
-
480
- stop: function() {
481
- if (!this.timer) return;
482
- clearInterval(this.timer);
483
- this.timer = null;
484
- },
485
-
486
- onTimerEvent: function() {
487
- if (!this.currentlyExecuting) {
488
- try {
489
- this.currentlyExecuting = true;
490
- this.execute();
491
- this.currentlyExecuting = false;
492
- } catch(e) {
493
- this.currentlyExecuting = false;
494
- throw e;
495
- }
496
- }
497
- }
498
- });
499
- Object.extend(String, {
500
- interpret: function(value) {
501
- return value == null ? '' : String(value);
502
- },
503
- specialChar: {
504
- '\b': '\\b',
505
- '\t': '\\t',
506
- '\n': '\\n',
507
- '\f': '\\f',
508
- '\r': '\\r',
509
- '\\': '\\\\'
510
- }
511
- });
512
-
513
- Object.extend(String.prototype, (function() {
514
- var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
515
- typeof JSON.parse === 'function' &&
516
- JSON.parse('{"test": true}').test;
517
-
518
- function prepareReplacement(replacement) {
519
- if (Object.isFunction(replacement)) return replacement;
520
- var template = new Template(replacement);
521
- return function(match) { return template.evaluate(match) };
522
- }
523
-
524
- function gsub(pattern, replacement) {
525
- var result = '', source = this, match;
526
- replacement = prepareReplacement(replacement);
527
-
528
- if (Object.isString(pattern))
529
- pattern = RegExp.escape(pattern);
530
-
531
- if (!(pattern.length || pattern.source)) {
532
- replacement = replacement('');
533
- return replacement + source.split('').join(replacement) + replacement;
534
- }
535
-
536
- while (source.length > 0) {
537
- if (match = source.match(pattern)) {
538
- result += source.slice(0, match.index);
539
- result += String.interpret(replacement(match));
540
- source = source.slice(match.index + match[0].length);
541
- } else {
542
- result += source, source = '';
543
- }
544
- }
545
- return result;
546
- }
547
-
548
- function sub(pattern, replacement, count) {
549
- replacement = prepareReplacement(replacement);
550
- count = Object.isUndefined(count) ? 1 : count;
551
-
552
- return this.gsub(pattern, function(match) {
553
- if (--count < 0) return match[0];
554
- return replacement(match);
555
- });
556
- }
557
-
558
- function scan(pattern, iterator) {
559
- this.gsub(pattern, iterator);
560
- return String(this);
561
- }
562
-
563
- function truncate(length, truncation) {
564
- length = length || 30;
565
- truncation = Object.isUndefined(truncation) ? '...' : truncation;
566
- return this.length > length ?
567
- this.slice(0, length - truncation.length) + truncation : String(this);
568
- }
569
-
570
- function strip() {
571
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
572
- }
573
-
574
- function stripTags() {
575
- return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
576
- }
577
-
578
- function stripScripts() {
579
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
580
- }
581
-
582
- function extractScripts() {
583
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
584
- matchOne = new RegExp(Prototype.ScriptFragment, 'im');
585
- return (this.match(matchAll) || []).map(function(scriptTag) {
586
- return (scriptTag.match(matchOne) || ['', ''])[1];
587
- });
588
- }
589
-
590
- function evalScripts() {
591
- return this.extractScripts().map(function(script) { return eval(script) });
592
- }
593
-
594
- function escapeHTML() {
595
- return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
596
- }
597
-
598
- function unescapeHTML() {
599
- return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
600
- }
601
-
602
-
603
- function toQueryParams(separator) {
604
- var match = this.strip().match(/([^?#]*)(#.*)?$/);
605
- if (!match) return { };
606
-
607
- return match[1].split(separator || '&').inject({ }, function(hash, pair) {
608
- if ((pair = pair.split('='))[0]) {
609
- var key = decodeURIComponent(pair.shift()),
610
- value = pair.length > 1 ? pair.join('=') : pair[0];
611
-
612
- if (value != undefined) value = decodeURIComponent(value);
613
-
614
- if (key in hash) {
615
- if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
616
- hash[key].push(value);
617
- }
618
- else hash[key] = value;
619
- }
620
- return hash;
621
- });
622
- }
623
-
624
- function toArray() {
625
- return this.split('');
626
- }
627
-
628
- function succ() {
629
- return this.slice(0, this.length - 1) +
630
- String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
631
- }
632
-
633
- function times(count) {
634
- return count < 1 ? '' : new Array(count + 1).join(this);
635
- }
636
-
637
- function camelize() {
638
- return this.replace(/-+(.)?/g, function(match, chr) {
639
- return chr ? chr.toUpperCase() : '';
640
- });
641
- }
642
-
643
- function capitalize() {
644
- return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
645
- }
646
-
647
- function underscore() {
648
- return this.replace(/::/g, '/')
649
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
650
- .replace(/([a-z\d])([A-Z])/g, '$1_$2')
651
- .replace(/-/g, '_')
652
- .toLowerCase();
653
- }
654
-
655
- function dasherize() {
656
- return this.replace(/_/g, '-');
657
- }
658
-
659
- function inspect(useDoubleQuotes) {
660
- var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
661
- if (character in String.specialChar) {
662
- return String.specialChar[character];
663
- }
664
- return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
665
- });
666
- if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
667
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
668
- }
669
-
670
- function unfilterJSON(filter) {
671
- return this.replace(filter || Prototype.JSONFilter, '$1');
672
- }
673
-
674
- function isJSON() {
675
- var str = this;
676
- if (str.blank()) return false;
677
- str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
678
- str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
679
- str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
680
- return (/^[\],:{}\s]*$/).test(str);
681
- }
682
-
683
- function evalJSON(sanitize) {
684
- var json = this.unfilterJSON(),
685
- cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
686
- if (cx.test(json)) {
687
- json = json.replace(cx, function (a) {
688
- return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
689
- });
690
- }
691
- try {
692
- if (!sanitize || json.isJSON()) return eval('(' + json + ')');
693
- } catch (e) { }
694
- throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
695
- }
696
-
697
- function parseJSON() {
698
- var json = this.unfilterJSON();
699
- return JSON.parse(json);
700
- }
701
-
702
- function include(pattern) {
703
- return this.indexOf(pattern) > -1;
704
- }
705
-
706
- function startsWith(pattern) {
707
- return this.lastIndexOf(pattern, 0) === 0;
708
- }
709
-
710
- function endsWith(pattern) {
711
- var d = this.length - pattern.length;
712
- return d >= 0 && this.indexOf(pattern, d) === d;
713
- }
714
-
715
- function empty() {
716
- return this == '';
717
- }
718
-
719
- function blank() {
720
- return /^\s*$/.test(this);
721
- }
722
-
723
- function interpolate(object, pattern) {
724
- return new Template(this, pattern).evaluate(object);
725
- }
726
-
727
- return {
728
- gsub: gsub,
729
- sub: sub,
730
- scan: scan,
731
- truncate: truncate,
732
- strip: String.prototype.trim || strip,
733
- stripTags: stripTags,
734
- stripScripts: stripScripts,
735
- extractScripts: extractScripts,
736
- evalScripts: evalScripts,
737
- escapeHTML: escapeHTML,
738
- unescapeHTML: unescapeHTML,
739
- toQueryParams: toQueryParams,
740
- parseQuery: toQueryParams,
741
- toArray: toArray,
742
- succ: succ,
743
- times: times,
744
- camelize: camelize,
745
- capitalize: capitalize,
746
- underscore: underscore,
747
- dasherize: dasherize,
748
- inspect: inspect,
749
- unfilterJSON: unfilterJSON,
750
- isJSON: isJSON,
751
- evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
752
- include: include,
753
- startsWith: startsWith,
754
- endsWith: endsWith,
755
- empty: empty,
756
- blank: blank,
757
- interpolate: interpolate
758
- };
759
- })());
760
-
761
- var Template = Class.create({
762
- initialize: function(template, pattern) {
763
- this.template = template.toString();
764
- this.pattern = pattern || Template.Pattern;
765
- },
766
-
767
- evaluate: function(object) {
768
- if (object && Object.isFunction(object.toTemplateReplacements))
769
- object = object.toTemplateReplacements();
770
-
771
- return this.template.gsub(this.pattern, function(match) {
772
- if (object == null) return (match[1] + '');
773
-
774
- var before = match[1] || '';
775
- if (before == '\\') return match[2];
776
-
777
- var ctx = object, expr = match[3],
778
- pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
779
-
780
- match = pattern.exec(expr);
781
- if (match == null) return before;
782
-
783
- while (match != null) {
784
- var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
785
- ctx = ctx[comp];
786
- if (null == ctx || '' == match[3]) break;
787
- expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
788
- match = pattern.exec(expr);
789
- }
790
-
791
- return before + String.interpret(ctx);
792
- });
793
- }
794
- });
795
- Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
796
-
797
- var $break = { };
798
-
799
- var Enumerable = (function() {
800
- function each(iterator, context) {
801
- var index = 0;
802
- try {
803
- this._each(function(value) {
804
- iterator.call(context, value, index++);
805
- });
806
- } catch (e) {
807
- if (e != $break) throw e;
808
- }
809
- return this;
810
- }
811
-
812
- function eachSlice(number, iterator, context) {
813
- var index = -number, slices = [], array = this.toArray();
814
- if (number < 1) return array;
815
- while ((index += number) < array.length)
816
- slices.push(array.slice(index, index+number));
817
- return slices.collect(iterator, context);
818
- }
819
-
820
- function all(iterator, context) {
821
- iterator = iterator || Prototype.K;
822
- var result = true;
823
- this.each(function(value, index) {
824
- result = result && !!iterator.call(context, value, index);
825
- if (!result) throw $break;
826
- });
827
- return result;
828
- }
829
-
830
- function any(iterator, context) {
831
- iterator = iterator || Prototype.K;
832
- var result = false;
833
- this.each(function(value, index) {
834
- if (result = !!iterator.call(context, value, index))
835
- throw $break;
836
- });
837
- return result;
838
- }
839
-
840
- function collect(iterator, context) {
841
- iterator = iterator || Prototype.K;
842
- var results = [];
843
- this.each(function(value, index) {
844
- results.push(iterator.call(context, value, index));
845
- });
846
- return results;
847
- }
848
-
849
- function detect(iterator, context) {
850
- var result;
851
- this.each(function(value, index) {
852
- if (iterator.call(context, value, index)) {
853
- result = value;
854
- throw $break;
855
- }
856
- });
857
- return result;
858
- }
859
-
860
- function findAll(iterator, context) {
861
- var results = [];
862
- this.each(function(value, index) {
863
- if (iterator.call(context, value, index))
864
- results.push(value);
865
- });
866
- return results;
867
- }
868
-
869
- function grep(filter, iterator, context) {
870
- iterator = iterator || Prototype.K;
871
- var results = [];
872
-
873
- if (Object.isString(filter))
874
- filter = new RegExp(RegExp.escape(filter));
875
-
876
- this.each(function(value, index) {
877
- if (filter.match(value))
878
- results.push(iterator.call(context, value, index));
879
- });
880
- return results;
881
- }
882
-
883
- function include(object) {
884
- if (Object.isFunction(this.indexOf))
885
- if (this.indexOf(object) != -1) return true;
886
-
887
- var found = false;
888
- this.each(function(value) {
889
- if (value == object) {
890
- found = true;
891
- throw $break;
892
- }
893
- });
894
- return found;
895
- }
896
-
897
- function inGroupsOf(number, fillWith) {
898
- fillWith = Object.isUndefined(fillWith) ? null : fillWith;
899
- return this.eachSlice(number, function(slice) {
900
- while(slice.length < number) slice.push(fillWith);
901
- return slice;
902
- });
903
- }
904
-
905
- function inject(memo, iterator, context) {
906
- this.each(function(value, index) {
907
- memo = iterator.call(context, memo, value, index);
908
- });
909
- return memo;
910
- }
911
-
912
- function invoke(method) {
913
- var args = $A(arguments).slice(1);
914
- return this.map(function(value) {
915
- return value[method].apply(value, args);
916
- });
917
- }
918
-
919
- function max(iterator, context) {
920
- iterator = iterator || Prototype.K;
921
- var result;
922
- this.each(function(value, index) {
923
- value = iterator.call(context, value, index);
924
- if (result == null || value >= result)
925
- result = value;
926
- });
927
- return result;
928
- }
929
-
930
- function min(iterator, context) {
931
- iterator = iterator || Prototype.K;
932
- var result;
933
- this.each(function(value, index) {
934
- value = iterator.call(context, value, index);
935
- if (result == null || value < result)
936
- result = value;
937
- });
938
- return result;
939
- }
940
-
941
- function partition(iterator, context) {
942
- iterator = iterator || Prototype.K;
943
- var trues = [], falses = [];
944
- this.each(function(value, index) {
945
- (iterator.call(context, value, index) ?
946
- trues : falses).push(value);
947
- });
948
- return [trues, falses];
949
- }
950
-
951
- function pluck(property) {
952
- var results = [];
953
- this.each(function(value) {
954
- results.push(value[property]);
955
- });
956
- return results;
957
- }
958
-
959
- function reject(iterator, context) {
960
- var results = [];
961
- this.each(function(value, index) {
962
- if (!iterator.call(context, value, index))
963
- results.push(value);
964
- });
965
- return results;
966
- }
967
-
968
- function sortBy(iterator, context) {
969
- return this.map(function(value, index) {
970
- return {
971
- value: value,
972
- criteria: iterator.call(context, value, index)
973
- };
974
- }).sort(function(left, right) {
975
- var a = left.criteria, b = right.criteria;
976
- return a < b ? -1 : a > b ? 1 : 0;
977
- }).pluck('value');
978
- }
979
-
980
- function toArray() {
981
- return this.map();
982
- }
983
-
984
- function zip() {
985
- var iterator = Prototype.K, args = $A(arguments);
986
- if (Object.isFunction(args.last()))
987
- iterator = args.pop();
988
-
989
- var collections = [this].concat(args).map($A);
990
- return this.map(function(value, index) {
991
- return iterator(collections.pluck(index));
992
- });
993
- }
994
-
995
- function size() {
996
- return this.toArray().length;
997
- }
998
-
999
- function inspect() {
1000
- return '#<Enumerable:' + this.toArray().inspect() + '>';
1001
- }
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
-
1009
-
1010
-
1011
- return {
1012
- each: each,
1013
- eachSlice: eachSlice,
1014
- all: all,
1015
- every: all,
1016
- any: any,
1017
- some: any,
1018
- collect: collect,
1019
- map: collect,
1020
- detect: detect,
1021
- findAll: findAll,
1022
- select: findAll,
1023
- filter: findAll,
1024
- grep: grep,
1025
- include: include,
1026
- member: include,
1027
- inGroupsOf: inGroupsOf,
1028
- inject: inject,
1029
- invoke: invoke,
1030
- max: max,
1031
- min: min,
1032
- partition: partition,
1033
- pluck: pluck,
1034
- reject: reject,
1035
- sortBy: sortBy,
1036
- toArray: toArray,
1037
- entries: toArray,
1038
- zip: zip,
1039
- size: size,
1040
- inspect: inspect,
1041
- find: detect
1042
- };
1043
- })();
1044
-
1045
- function $A(iterable) {
1046
- if (!iterable) return [];
1047
- if ('toArray' in Object(iterable)) return iterable.toArray();
1048
- var length = iterable.length || 0, results = new Array(length);
1049
- while (length--) results[length] = iterable[length];
1050
- return results;
1051
- }
1052
-
1053
-
1054
- function $w(string) {
1055
- if (!Object.isString(string)) return [];
1056
- string = string.strip();
1057
- return string ? string.split(/\s+/) : [];
1058
- }
1059
-
1060
- Array.from = $A;
1061
-
1062
-
1063
- (function() {
1064
- var arrayProto = Array.prototype,
1065
- slice = arrayProto.slice,
1066
- _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
1067
-
1068
- function each(iterator, context) {
1069
- for (var i = 0, length = this.length >>> 0; i < length; i++) {
1070
- if (i in this) iterator.call(context, this[i], i, this);
1071
- }
1072
- }
1073
- if (!_each) _each = each;
1074
-
1075
- function clear() {
1076
- this.length = 0;
1077
- return this;
1078
- }
1079
-
1080
- function first() {
1081
- return this[0];
1082
- }
1083
-
1084
- function last() {
1085
- return this[this.length - 1];
1086
- }
1087
-
1088
- function compact() {
1089
- return this.select(function(value) {
1090
- return value != null;
1091
- });
1092
- }
1093
-
1094
- function flatten() {
1095
- return this.inject([], function(array, value) {
1096
- if (Object.isArray(value))
1097
- return array.concat(value.flatten());
1098
- array.push(value);
1099
- return array;
1100
- });
1101
- }
1102
-
1103
- function without() {
1104
- var values = slice.call(arguments, 0);
1105
- return this.select(function(value) {
1106
- return !values.include(value);
1107
- });
1108
- }
1109
-
1110
- function reverse(inline) {
1111
- return (inline === false ? this.toArray() : this)._reverse();
1112
- }
1113
-
1114
- function uniq(sorted) {
1115
- return this.inject([], function(array, value, index) {
1116
- if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1117
- array.push(value);
1118
- return array;
1119
- });
1120
- }
1121
-
1122
- function intersect(array) {
1123
- return this.uniq().findAll(function(item) {
1124
- return array.detect(function(value) { return item === value });
1125
- });
1126
- }
1127
-
1128
-
1129
- function clone() {
1130
- return slice.call(this, 0);
1131
- }
1132
-
1133
- function size() {
1134
- return this.length;
1135
- }
1136
-
1137
- function inspect() {
1138
- return '[' + this.map(Object.inspect).join(', ') + ']';
1139
- }
1140
-
1141
- function indexOf(item, i) {
1142
- i || (i = 0);
1143
- var length = this.length;
1144
- if (i < 0) i = length + i;
1145
- for (; i < length; i++)
1146
- if (this[i] === item) return i;
1147
- return -1;
1148
- }
1149
-
1150
- function lastIndexOf(item, i) {
1151
- i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
1152
- var n = this.slice(0, i).reverse().indexOf(item);
1153
- return (n < 0) ? n : i - n - 1;
1154
- }
1155
-
1156
- function concat() {
1157
- var array = slice.call(this, 0), item;
1158
- for (var i = 0, length = arguments.length; i < length; i++) {
1159
- item = arguments[i];
1160
- if (Object.isArray(item) && !('callee' in item)) {
1161
- for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
1162
- array.push(item[j]);
1163
- } else {
1164
- array.push(item);
1165
- }
1166
- }
1167
- return array;
1168
- }
1169
-
1170
- Object.extend(arrayProto, Enumerable);
1171
-
1172
- if (!arrayProto._reverse)
1173
- arrayProto._reverse = arrayProto.reverse;
1174
-
1175
- Object.extend(arrayProto, {
1176
- _each: _each,
1177
- clear: clear,
1178
- first: first,
1179
- last: last,
1180
- compact: compact,
1181
- flatten: flatten,
1182
- without: without,
1183
- reverse: reverse,
1184
- uniq: uniq,
1185
- intersect: intersect,
1186
- clone: clone,
1187
- toArray: clone,
1188
- size: size,
1189
- inspect: inspect
1190
- });
1191
-
1192
- var CONCAT_ARGUMENTS_BUGGY = (function() {
1193
- return [].concat(arguments)[0][0] !== 1;
1194
- })(1,2)
1195
-
1196
- if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1197
-
1198
- if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1199
- if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1200
- })();
1201
- function $H(object) {
1202
- return new Hash(object);
1203
- };
1204
-
1205
- var Hash = Class.create(Enumerable, (function() {
1206
- function initialize(object) {
1207
- this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1208
- }
1209
-
1210
-
1211
- function _each(iterator) {
1212
- for (var key in this._object) {
1213
- var value = this._object[key], pair = [key, value];
1214
- pair.key = key;
1215
- pair.value = value;
1216
- iterator(pair);
1217
- }
1218
- }
1219
-
1220
- function set(key, value) {
1221
- return this._object[key] = value;
1222
- }
1223
-
1224
- function get(key) {
1225
- if (this._object[key] !== Object.prototype[key])
1226
- return this._object[key];
1227
- }
1228
-
1229
- function unset(key) {
1230
- var value = this._object[key];
1231
- delete this._object[key];
1232
- return value;
1233
- }
1234
-
1235
- function toObject() {
1236
- return Object.clone(this._object);
1237
- }
1238
-
1239
-
1240
-
1241
- function keys() {
1242
- return this.pluck('key');
1243
- }
1244
-
1245
- function values() {
1246
- return this.pluck('value');
1247
- }
1248
-
1249
- function index(value) {
1250
- var match = this.detect(function(pair) {
1251
- return pair.value === value;
1252
- });
1253
- return match && match.key;
1254
- }
1255
-
1256
- function merge(object) {
1257
- return this.clone().update(object);
1258
- }
1259
-
1260
- function update(object) {
1261
- return new Hash(object).inject(this, function(result, pair) {
1262
- result.set(pair.key, pair.value);
1263
- return result;
1264
- });
1265
- }
1266
-
1267
- function toQueryPair(key, value) {
1268
- if (Object.isUndefined(value)) return key;
1269
- return key + '=' + encodeURIComponent(String.interpret(value));
1270
- }
1271
-
1272
- function toQueryString() {
1273
- return this.inject([], function(results, pair) {
1274
- var key = encodeURIComponent(pair.key), values = pair.value;
1275
-
1276
- if (values && typeof values == 'object') {
1277
- if (Object.isArray(values)) {
1278
- var queryValues = [];
1279
- for (var i = 0, len = values.length, value; i < len; i++) {
1280
- value = values[i];
1281
- queryValues.push(toQueryPair(key, value));
1282
- }
1283
- return results.concat(queryValues);
1284
- }
1285
- } else results.push(toQueryPair(key, values));
1286
- return results;
1287
- }).join('&');
1288
- }
1289
-
1290
- function inspect() {
1291
- return '#<Hash:{' + this.map(function(pair) {
1292
- return pair.map(Object.inspect).join(': ');
1293
- }).join(', ') + '}>';
1294
- }
1295
-
1296
- function clone() {
1297
- return new Hash(this);
1298
- }
1299
-
1300
- return {
1301
- initialize: initialize,
1302
- _each: _each,
1303
- set: set,
1304
- get: get,
1305
- unset: unset,
1306
- toObject: toObject,
1307
- toTemplateReplacements: toObject,
1308
- keys: keys,
1309
- values: values,
1310
- index: index,
1311
- merge: merge,
1312
- update: update,
1313
- toQueryString: toQueryString,
1314
- inspect: inspect,
1315
- toJSON: toObject,
1316
- clone: clone
1317
- };
1318
- })());
1319
-
1320
- Hash.from = $H;
1321
- Object.extend(Number.prototype, (function() {
1322
- function toColorPart() {
1323
- return this.toPaddedString(2, 16);
1324
- }
1325
-
1326
- function succ() {
1327
- return this + 1;
1328
- }
1329
-
1330
- function times(iterator, context) {
1331
- $R(0, this, true).each(iterator, context);
1332
- return this;
1333
- }
1334
-
1335
- function toPaddedString(length, radix) {
1336
- var string = this.toString(radix || 10);
1337
- return '0'.times(length - string.length) + string;
1338
- }
1339
-
1340
- function abs() {
1341
- return Math.abs(this);
1342
- }
1343
-
1344
- function round() {
1345
- return Math.round(this);
1346
- }
1347
-
1348
- function ceil() {
1349
- return Math.ceil(this);
1350
- }
1351
-
1352
- function floor() {
1353
- return Math.floor(this);
1354
- }
1355
-
1356
- return {
1357
- toColorPart: toColorPart,
1358
- succ: succ,
1359
- times: times,
1360
- toPaddedString: toPaddedString,
1361
- abs: abs,
1362
- round: round,
1363
- ceil: ceil,
1364
- floor: floor
1365
- };
1366
- })());
1367
-
1368
- function $R(start, end, exclusive) {
1369
- return new ObjectRange(start, end, exclusive);
1370
- }
1371
-
1372
- var ObjectRange = Class.create(Enumerable, (function() {
1373
- function initialize(start, end, exclusive) {
1374
- this.start = start;
1375
- this.end = end;
1376
- this.exclusive = exclusive;
1377
- }
1378
-
1379
- function _each(iterator) {
1380
- var value = this.start;
1381
- while (this.include(value)) {
1382
- iterator(value);
1383
- value = value.succ();
1384
- }
1385
- }
1386
-
1387
- function include(value) {
1388
- if (value < this.start)
1389
- return false;
1390
- if (this.exclusive)
1391
- return value < this.end;
1392
- return value <= this.end;
1393
- }
1394
-
1395
- return {
1396
- initialize: initialize,
1397
- _each: _each,
1398
- include: include
1399
- };
1400
- })());
1401
-
1402
-
1403
-
1404
- var Abstract = { };
1405
-
1406
-
1407
- var Try = {
1408
- these: function() {
1409
- var returnValue;
1410
-
1411
- for (var i = 0, length = arguments.length; i < length; i++) {
1412
- var lambda = arguments[i];
1413
- try {
1414
- returnValue = lambda();
1415
- break;
1416
- } catch (e) { }
1417
- }
1418
-
1419
- return returnValue;
1420
- }
1421
- };
1422
-
1423
- var Ajax = {
1424
- getTransport: function() {
1425
- return Try.these(
1426
- function() {return new XMLHttpRequest()},
1427
- function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1428
- function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1429
- ) || false;
1430
- },
1431
-
1432
- activeRequestCount: 0
1433
- };
1434
-
1435
- Ajax.Responders = {
1436
- responders: [],
1437
-
1438
- _each: function(iterator) {
1439
- this.responders._each(iterator);
1440
- },
1441
-
1442
- register: function(responder) {
1443
- if (!this.include(responder))
1444
- this.responders.push(responder);
1445
- },
1446
-
1447
- unregister: function(responder) {
1448
- this.responders = this.responders.without(responder);
1449
- },
1450
-
1451
- dispatch: function(callback, request, transport, json) {
1452
- this.each(function(responder) {
1453
- if (Object.isFunction(responder[callback])) {
1454
- try {
1455
- responder[callback].apply(responder, [request, transport, json]);
1456
- } catch (e) { }
1457
- }
1458
- });
1459
- }
1460
- };
1461
-
1462
- Object.extend(Ajax.Responders, Enumerable);
1463
-
1464
- Ajax.Responders.register({
1465
- onCreate: function() { Ajax.activeRequestCount++ },
1466
- onComplete: function() { Ajax.activeRequestCount-- }
1467
- });
1468
- Ajax.Base = Class.create({
1469
- initialize: function(options) {
1470
- this.options = {
1471
- method: 'post',
1472
- asynchronous: true,
1473
- contentType: 'application/x-www-form-urlencoded',
1474
- encoding: 'UTF-8',
1475
- parameters: '',
1476
- evalJSON: true,
1477
- evalJS: true
1478
- };
1479
- Object.extend(this.options, options || { });
1480
-
1481
- this.options.method = this.options.method.toLowerCase();
1482
-
1483
- if (Object.isHash(this.options.parameters))
1484
- this.options.parameters = this.options.parameters.toObject();
1485
- }
1486
- });
1487
- Ajax.Request = Class.create(Ajax.Base, {
1488
- _complete: false,
1489
-
1490
- initialize: function($super, url, options) {
1491
- $super(options);
1492
- this.transport = Ajax.getTransport();
1493
- this.request(url);
1494
- },
1495
-
1496
- request: function(url) {
1497
- this.url = url;
1498
- this.method = this.options.method;
1499
- var params = Object.isString(this.options.parameters) ?
1500
- this.options.parameters :
1501
- Object.toQueryString(this.options.parameters);
1502
-
1503
- if (!['get', 'post'].include(this.method)) {
1504
- params += (params ? '&' : '') + "_method=" + this.method;
1505
- this.method = 'post';
1506
- }
1507
-
1508
- if (params && this.method === 'get') {
1509
- this.url += (this.url.include('?') ? '&' : '?') + params;
1510
- }
1511
-
1512
- this.parameters = params.toQueryParams();
1513
-
1514
- try {
1515
- var response = new Ajax.Response(this);
1516
- if (this.options.onCreate) this.options.onCreate(response);
1517
- Ajax.Responders.dispatch('onCreate', this, response);
1518
-
1519
- this.transport.open(this.method.toUpperCase(), this.url,
1520
- this.options.asynchronous);
1521
-
1522
- if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
1523
-
1524
- this.transport.onreadystatechange = this.onStateChange.bind(this);
1525
- this.setRequestHeaders();
1526
-
1527
- this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1528
- this.transport.send(this.body);
1529
-
1530
- /* Force Firefox to handle ready state 4 for synchronous requests */
1531
- if (!this.options.asynchronous && this.transport.overrideMimeType)
1532
- this.onStateChange();
1533
-
1534
- }
1535
- catch (e) {
1536
- this.dispatchException(e);
1537
- }
1538
- },
1539
-
1540
- onStateChange: function() {
1541
- var readyState = this.transport.readyState;
1542
- if (readyState > 1 && !((readyState == 4) && this._complete))
1543
- this.respondToReadyState(this.transport.readyState);
1544
- },
1545
-
1546
- setRequestHeaders: function() {
1547
- var headers = {
1548
- 'X-Requested-With': 'XMLHttpRequest',
1549
- 'X-Prototype-Version': Prototype.Version,
1550
- 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1551
- };
1552
-
1553
- if (this.method == 'post') {
1554
- headers['Content-type'] = this.options.contentType +
1555
- (this.options.encoding ? '; charset=' + this.options.encoding : '');
1556
-
1557
- /* Force "Connection: close" for older Mozilla browsers to work
1558
- * around a bug where XMLHttpRequest sends an incorrect
1559
- * Content-length header. See Mozilla Bugzilla #246651.
1560
- */
1561
- if (this.transport.overrideMimeType &&
1562
- (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1563
- headers['Connection'] = 'close';
1564
- }
1565
-
1566
- if (typeof this.options.requestHeaders == 'object') {
1567
- var extras = this.options.requestHeaders;
1568
-
1569
- if (Object.isFunction(extras.push))
1570
- for (var i = 0, length = extras.length; i < length; i += 2)
1571
- headers[extras[i]] = extras[i+1];
1572
- else
1573
- $H(extras).each(function(pair) { headers[pair.key] = pair.value });
1574
- }
1575
-
1576
- for (var name in headers)
1577
- this.transport.setRequestHeader(name, headers[name]);
1578
- },
1579
-
1580
- success: function() {
1581
- var status = this.getStatus();
1582
- return !status || (status >= 200 && status < 300) || status == 304;
1583
- },
1584
-
1585
- getStatus: function() {
1586
- try {
1587
- if (this.transport.status === 1223) return 204;
1588
- return this.transport.status || 0;
1589
- } catch (e) { return 0 }
1590
- },
1591
-
1592
- respondToReadyState: function(readyState) {
1593
- var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1594
-
1595
- if (state == 'Complete') {
1596
- try {
1597
- this._complete = true;
1598
- (this.options['on' + response.status]
1599
- || this.options['on' + (this.success() ? 'Success' : 'Failure')]
1600
- || Prototype.emptyFunction)(response, response.headerJSON);
1601
- } catch (e) {
1602
- this.dispatchException(e);
1603
- }
1604
-
1605
- var contentType = response.getHeader('Content-type');
1606
- if (this.options.evalJS == 'force'
1607
- || (this.options.evalJS && this.isSameOrigin() && contentType
1608
- && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1609
- this.evalResponse();
1610
- }
1611
-
1612
- try {
1613
- (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1614
- Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
1615
- } catch (e) {
1616
- this.dispatchException(e);
1617
- }
1618
-
1619
- if (state == 'Complete') {
1620
- this.transport.onreadystatechange = Prototype.emptyFunction;
1621
- }
1622
- },
1623
-
1624
- isSameOrigin: function() {
1625
- var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1626
- return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1627
- protocol: location.protocol,
1628
- domain: document.domain,
1629
- port: location.port ? ':' + location.port : ''
1630
- }));
1631
- },
1632
-
1633
- getHeader: function(name) {
1634
- try {
1635
- return this.transport.getResponseHeader(name) || null;
1636
- } catch (e) { return null; }
1637
- },
1638
-
1639
- evalResponse: function() {
1640
- try {
1641
- return eval((this.transport.responseText || '').unfilterJSON());
1642
- } catch (e) {
1643
- this.dispatchException(e);
1644
- }
1645
- },
1646
-
1647
- dispatchException: function(exception) {
1648
- (this.options.onException || Prototype.emptyFunction)(this, exception);
1649
- Ajax.Responders.dispatch('onException', this, exception);
1650
- }
1651
- });
1652
-
1653
- Ajax.Request.Events =
1654
- ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1655
-
1656
-
1657
-
1658
-
1659
-
1660
-
1661
-
1662
-
1663
- Ajax.Response = Class.create({
1664
- initialize: function(request){
1665
- this.request = request;
1666
- var transport = this.transport = request.transport,
1667
- readyState = this.readyState = transport.readyState;
1668
-
1669
- if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1670
- this.status = this.getStatus();
1671
- this.statusText = this.getStatusText();
1672
- this.responseText = String.interpret(transport.responseText);
1673
- this.headerJSON = this._getHeaderJSON();
1674
- }
1675
-
1676
- if (readyState == 4) {
1677
- var xml = transport.responseXML;
1678
- this.responseXML = Object.isUndefined(xml) ? null : xml;
1679
- this.responseJSON = this._getResponseJSON();
1680
- }
1681
- },
1682
-
1683
- status: 0,
1684
-
1685
- statusText: '',
1686
-
1687
- getStatus: Ajax.Request.prototype.getStatus,
1688
-
1689
- getStatusText: function() {
1690
- try {
1691
- return this.transport.statusText || '';
1692
- } catch (e) { return '' }
1693
- },
1694
-
1695
- getHeader: Ajax.Request.prototype.getHeader,
1696
-
1697
- getAllHeaders: function() {
1698
- try {
1699
- return this.getAllResponseHeaders();
1700
- } catch (e) { return null }
1701
- },
1702
-
1703
- getResponseHeader: function(name) {
1704
- return this.transport.getResponseHeader(name);
1705
- },
1706
-
1707
- getAllResponseHeaders: function() {
1708
- return this.transport.getAllResponseHeaders();
1709
- },
1710
-
1711
- _getHeaderJSON: function() {
1712
- var json = this.getHeader('X-JSON');
1713
- if (!json) return null;
1714
- json = decodeURIComponent(escape(json));
1715
- try {
1716
- return json.evalJSON(this.request.options.sanitizeJSON ||
1717
- !this.request.isSameOrigin());
1718
- } catch (e) {
1719
- this.request.dispatchException(e);
1720
- }
1721
- },
1722
-
1723
- _getResponseJSON: function() {
1724
- var options = this.request.options;
1725
- if (!options.evalJSON || (options.evalJSON != 'force' &&
1726
- !(this.getHeader('Content-type') || '').include('application/json')) ||
1727
- this.responseText.blank())
1728
- return null;
1729
- try {
1730
- return this.responseText.evalJSON(options.sanitizeJSON ||
1731
- !this.request.isSameOrigin());
1732
- } catch (e) {
1733
- this.request.dispatchException(e);
1734
- }
1735
- }
1736
- });
1737
-
1738
- Ajax.Updater = Class.create(Ajax.Request, {
1739
- initialize: function($super, container, url, options) {
1740
- this.container = {
1741
- success: (container.success || container),
1742
- failure: (container.failure || (container.success ? null : container))
1743
- };
1744
-
1745
- options = Object.clone(options);
1746
- var onComplete = options.onComplete;
1747
- options.onComplete = (function(response, json) {
1748
- this.updateContent(response.responseText);
1749
- if (Object.isFunction(onComplete)) onComplete(response, json);
1750
- }).bind(this);
1751
-
1752
- $super(url, options);
1753
- },
1754
-
1755
- updateContent: function(responseText) {
1756
- var receiver = this.container[this.success() ? 'success' : 'failure'],
1757
- options = this.options;
1758
-
1759
- if (!options.evalScripts) responseText = responseText.stripScripts();
1760
-
1761
- if (receiver = $(receiver)) {
1762
- if (options.insertion) {
1763
- if (Object.isString(options.insertion)) {
1764
- var insertion = { }; insertion[options.insertion] = responseText;
1765
- receiver.insert(insertion);
1766
- }
1767
- else options.insertion(receiver, responseText);
1768
- }
1769
- else receiver.update(responseText);
1770
- }
1771
- }
1772
- });
1773
-
1774
- Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1775
- initialize: function($super, container, url, options) {
1776
- $super(options);
1777
- this.onComplete = this.options.onComplete;
1778
-
1779
- this.frequency = (this.options.frequency || 2);
1780
- this.decay = (this.options.decay || 1);
1781
-
1782
- this.updater = { };
1783
- this.container = container;
1784
- this.url = url;
1785
-
1786
- this.start();
1787
- },
1788
-
1789
- start: function() {
1790
- this.options.onComplete = this.updateComplete.bind(this);
1791
- this.onTimerEvent();
1792
- },
1793
-
1794
- stop: function() {
1795
- this.updater.options.onComplete = undefined;
1796
- clearTimeout(this.timer);
1797
- (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
1798
- },
1799
-
1800
- updateComplete: function(response) {
1801
- if (this.options.decay) {
1802
- this.decay = (response.responseText == this.lastText ?
1803
- this.decay * this.options.decay : 1);
1804
-
1805
- this.lastText = response.responseText;
1806
- }
1807
- this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
1808
- },
1809
-
1810
- onTimerEvent: function() {
1811
- this.updater = new Ajax.Updater(this.container, this.url, this.options);
1812
- }
1813
- });
1814
-
1815
-
1816
- function $(element) {
1817
- if (arguments.length > 1) {
1818
- for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1819
- elements.push($(arguments[i]));
1820
- return elements;
1821
- }
1822
- if (Object.isString(element))
1823
- element = document.getElementById(element);
1824
- return Element.extend(element);
1825
- }
1826
-
1827
- if (Prototype.BrowserFeatures.XPath) {
1828
- document._getElementsByXPath = function(expression, parentElement) {
1829
- var results = [];
1830
- var query = document.evaluate(expression, $(parentElement) || document,
1831
- null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1832
- for (var i = 0, length = query.snapshotLength; i < length; i++)
1833
- results.push(Element.extend(query.snapshotItem(i)));
1834
- return results;
1835
- };
1836
- }
1837
-
1838
- /*--------------------------------------------------------------------------*/
1839
-
1840
- if (!Node) var Node = { };
1841
-
1842
- if (!Node.ELEMENT_NODE) {
1843
- Object.extend(Node, {
1844
- ELEMENT_NODE: 1,
1845
- ATTRIBUTE_NODE: 2,
1846
- TEXT_NODE: 3,
1847
- CDATA_SECTION_NODE: 4,
1848
- ENTITY_REFERENCE_NODE: 5,
1849
- ENTITY_NODE: 6,
1850
- PROCESSING_INSTRUCTION_NODE: 7,
1851
- COMMENT_NODE: 8,
1852
- DOCUMENT_NODE: 9,
1853
- DOCUMENT_TYPE_NODE: 10,
1854
- DOCUMENT_FRAGMENT_NODE: 11,
1855
- NOTATION_NODE: 12
1856
- });
1857
- }
1858
-
1859
-
1860
-
1861
- (function(global) {
1862
- function shouldUseCache(tagName, attributes) {
1863
- if (tagName === 'select') return false;
1864
- if ('type' in attributes) return false;
1865
- return true;
1866
- }
1867
-
1868
- var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
1869
- try {
1870
- var el = document.createElement('<input name="x">');
1871
- return el.tagName.toLowerCase() === 'input' && el.name === 'x';
1872
- }
1873
- catch(err) {
1874
- return false;
1875
- }
1876
- })();
1877
-
1878
- var element = global.Element;
1879
-
1880
- global.Element = function(tagName, attributes) {
1881
- attributes = attributes || { };
1882
- tagName = tagName.toLowerCase();
1883
- var cache = Element.cache;
1884
-
1885
- if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
1886
- tagName = '<' + tagName + ' name="' + attributes.name + '">';
1887
- delete attributes.name;
1888
- return Element.writeAttribute(document.createElement(tagName), attributes);
1889
- }
1890
-
1891
- if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
1892
-
1893
- var node = shouldUseCache(tagName, attributes) ?
1894
- cache[tagName].cloneNode(false) : document.createElement(tagName);
1895
-
1896
- return Element.writeAttribute(node, attributes);
1897
- };
1898
-
1899
- Object.extend(global.Element, element || { });
1900
- if (element) global.Element.prototype = element.prototype;
1901
-
1902
- })(this);
1903
-
1904
- Element.idCounter = 1;
1905
- Element.cache = { };
1906
-
1907
- Element._purgeElement = function(element) {
1908
- var uid = element._prototypeUID;
1909
- if (uid) {
1910
- Element.stopObserving(element);
1911
- element._prototypeUID = void 0;
1912
- delete Element.Storage[uid];
1913
- }
1914
- }
1915
-
1916
- Element.Methods = {
1917
- visible: function(element) {
1918
- return $(element).style.display != 'none';
1919
- },
1920
-
1921
- toggle: function(element) {
1922
- element = $(element);
1923
- Element[Element.visible(element) ? 'hide' : 'show'](element);
1924
- return element;
1925
- },
1926
-
1927
- hide: function(element) {
1928
- element = $(element);
1929
- element.style.display = 'none';
1930
- return element;
1931
- },
1932
-
1933
- show: function(element) {
1934
- element = $(element);
1935
- element.style.display = '';
1936
- return element;
1937
- },
1938
-
1939
- remove: function(element) {
1940
- element = $(element);
1941
- element.parentNode.removeChild(element);
1942
- return element;
1943
- },
1944
-
1945
- update: (function(){
1946
-
1947
- var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
1948
- var el = document.createElement("select"),
1949
- isBuggy = true;
1950
- el.innerHTML = "<option value=\"test\">test</option>";
1951
- if (el.options && el.options[0]) {
1952
- isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
1953
- }
1954
- el = null;
1955
- return isBuggy;
1956
- })();
1957
-
1958
- var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
1959
- try {
1960
- var el = document.createElement("table");
1961
- if (el && el.tBodies) {
1962
- el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
1963
- var isBuggy = typeof el.tBodies[0] == "undefined";
1964
- el = null;
1965
- return isBuggy;
1966
- }
1967
- } catch (e) {
1968
- return true;
1969
- }
1970
- })();
1971
-
1972
- var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
1973
- try {
1974
- var el = document.createElement('div');
1975
- el.innerHTML = "<link>";
1976
- var isBuggy = (el.childNodes.length === 0);
1977
- el = null;
1978
- return isBuggy;
1979
- } catch(e) {
1980
- return true;
1981
- }
1982
- })();
1983
-
1984
- var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
1985
- TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
1986
-
1987
- var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
1988
- var s = document.createElement("script"),
1989
- isBuggy = false;
1990
- try {
1991
- s.appendChild(document.createTextNode(""));
1992
- isBuggy = !s.firstChild ||
1993
- s.firstChild && s.firstChild.nodeType !== 3;
1994
- } catch (e) {
1995
- isBuggy = true;
1996
- }
1997
- s = null;
1998
- return isBuggy;
1999
- })();
2000
-
2001
-
2002
- function update(element, content) {
2003
- element = $(element);
2004
- var purgeElement = Element._purgeElement;
2005
-
2006
- var descendants = element.getElementsByTagName('*'),
2007
- i = descendants.length;
2008
- while (i--) purgeElement(descendants[i]);
2009
-
2010
- if (content && content.toElement)
2011
- content = content.toElement();
2012
-
2013
- if (Object.isElement(content))
2014
- return element.update().insert(content);
2015
-
2016
- content = Object.toHTML(content);
2017
-
2018
- var tagName = element.tagName.toUpperCase();
2019
-
2020
- if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
2021
- element.text = content;
2022
- return element;
2023
- }
2024
-
2025
- if (ANY_INNERHTML_BUGGY) {
2026
- if (tagName in Element._insertionTranslations.tags) {
2027
- while (element.firstChild) {
2028
- element.removeChild(element.firstChild);
2029
- }
2030
- Element._getContentFromAnonymousElement(tagName, content.stripScripts())
2031
- .each(function(node) {
2032
- element.appendChild(node)
2033
- });
2034
- } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
2035
- while (element.firstChild) {
2036
- element.removeChild(element.firstChild);
2037
- }
2038
- var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
2039
- nodes.each(function(node) { element.appendChild(node) });
2040
- }
2041
- else {
2042
- element.innerHTML = content.stripScripts();
2043
- }
2044
- }
2045
- else {
2046
- element.innerHTML = content.stripScripts();
2047
- }
2048
-
2049
- content.evalScripts.bind(content).defer();
2050
- return element;
2051
- }
2052
-
2053
- return update;
2054
- })(),
2055
-
2056
- replace: function(element, content) {
2057
- element = $(element);
2058
- if (content && content.toElement) content = content.toElement();
2059
- else if (!Object.isElement(content)) {
2060
- content = Object.toHTML(content);
2061
- var range = element.ownerDocument.createRange();
2062
- range.selectNode(element);
2063
- content.evalScripts.bind(content).defer();
2064
- content = range.createContextualFragment(content.stripScripts());
2065
- }
2066
- element.parentNode.replaceChild(content, element);
2067
- return element;
2068
- },
2069
-
2070
- insert: function(element, insertions) {
2071
- element = $(element);
2072
-
2073
- if (Object.isString(insertions) || Object.isNumber(insertions) ||
2074
- Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
2075
- insertions = {bottom:insertions};
2076
-
2077
- var content, insert, tagName, childNodes;
2078
-
2079
- for (var position in insertions) {
2080
- content = insertions[position];
2081
- position = position.toLowerCase();
2082
- insert = Element._insertionTranslations[position];
2083
-
2084
- if (content && content.toElement) content = content.toElement();
2085
- if (Object.isElement(content)) {
2086
- insert(element, content);
2087
- continue;
2088
- }
2089
-
2090
- content = Object.toHTML(content);
2091
-
2092
- tagName = ((position == 'before' || position == 'after')
2093
- ? element.parentNode : element).tagName.toUpperCase();
2094
-
2095
- childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2096
-
2097
- if (position == 'top' || position == 'after') childNodes.reverse();
2098
- childNodes.each(insert.curry(element));
2099
-
2100
- content.evalScripts.bind(content).defer();
2101
- }
2102
-
2103
- return element;
2104
- },
2105
-
2106
- wrap: function(element, wrapper, attributes) {
2107
- element = $(element);
2108
- if (Object.isElement(wrapper))
2109
- $(wrapper).writeAttribute(attributes || { });
2110
- else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
2111
- else wrapper = new Element('div', wrapper);
2112
- if (element.parentNode)
2113
- element.parentNode.replaceChild(wrapper, element);
2114
- wrapper.appendChild(element);
2115
- return wrapper;
2116
- },
2117
-
2118
- inspect: function(element) {
2119
- element = $(element);
2120
- var result = '<' + element.tagName.toLowerCase();
2121
- $H({'id': 'id', 'className': 'class'}).each(function(pair) {
2122
- var property = pair.first(),
2123
- attribute = pair.last(),
2124
- value = (element[property] || '').toString();
2125
- if (value) result += ' ' + attribute + '=' + value.inspect(true);
2126
- });
2127
- return result + '>';
2128
- },
2129
-
2130
- recursivelyCollect: function(element, property, maximumLength) {
2131
- element = $(element);
2132
- maximumLength = maximumLength || -1;
2133
- var elements = [];
2134
-
2135
- while (element = element[property]) {
2136
- if (element.nodeType == 1)
2137
- elements.push(Element.extend(element));
2138
- if (elements.length == maximumLength)
2139
- break;
2140
- }
2141
-
2142
- return elements;
2143
- },
2144
-
2145
- ancestors: function(element) {
2146
- return Element.recursivelyCollect(element, 'parentNode');
2147
- },
2148
-
2149
- descendants: function(element) {
2150
- return Element.select(element, "*");
2151
- },
2152
-
2153
- firstDescendant: function(element) {
2154
- element = $(element).firstChild;
2155
- while (element && element.nodeType != 1) element = element.nextSibling;
2156
- return $(element);
2157
- },
2158
-
2159
- immediateDescendants: function(element) {
2160
- var results = [], child = $(element).firstChild;
2161
- while (child) {
2162
- if (child.nodeType === 1) {
2163
- results.push(Element.extend(child));
2164
- }
2165
- child = child.nextSibling;
2166
- }
2167
- return results;
2168
- },
2169
-
2170
- previousSiblings: function(element, maximumLength) {
2171
- return Element.recursivelyCollect(element, 'previousSibling');
2172
- },
2173
-
2174
- nextSiblings: function(element) {
2175
- return Element.recursivelyCollect(element, 'nextSibling');
2176
- },
2177
-
2178
- siblings: function(element) {
2179
- element = $(element);
2180
- return Element.previousSiblings(element).reverse()
2181
- .concat(Element.nextSiblings(element));
2182
- },
2183
-
2184
- match: function(element, selector) {
2185
- element = $(element);
2186
- if (Object.isString(selector))
2187
- return Prototype.Selector.match(element, selector);
2188
- return selector.match(element);
2189
- },
2190
-
2191
- up: function(element, expression, index) {
2192
- element = $(element);
2193
- if (arguments.length == 1) return $(element.parentNode);
2194
- var ancestors = Element.ancestors(element);
2195
- return Object.isNumber(expression) ? ancestors[expression] :
2196
- Prototype.Selector.find(ancestors, expression, index);
2197
- },
2198
-
2199
- down: function(element, expression, index) {
2200
- element = $(element);
2201
- if (arguments.length == 1) return Element.firstDescendant(element);
2202
- return Object.isNumber(expression) ? Element.descendants(element)[expression] :
2203
- Element.select(element, expression)[index || 0];
2204
- },
2205
-
2206
- previous: function(element, expression, index) {
2207
- element = $(element);
2208
- if (Object.isNumber(expression)) index = expression, expression = false;
2209
- if (!Object.isNumber(index)) index = 0;
2210
-
2211
- if (expression) {
2212
- return Prototype.Selector.find(element.previousSiblings(), expression, index);
2213
- } else {
2214
- return element.recursivelyCollect("previousSibling", index + 1)[index];
2215
- }
2216
- },
2217
-
2218
- next: function(element, expression, index) {
2219
- element = $(element);
2220
- if (Object.isNumber(expression)) index = expression, expression = false;
2221
- if (!Object.isNumber(index)) index = 0;
2222
-
2223
- if (expression) {
2224
- return Prototype.Selector.find(element.nextSiblings(), expression, index);
2225
- } else {
2226
- var maximumLength = Object.isNumber(index) ? index + 1 : 1;
2227
- return element.recursivelyCollect("nextSibling", index + 1)[index];
2228
- }
2229
- },
2230
-
2231
-
2232
- select: function(element) {
2233
- element = $(element);
2234
- var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2235
- return Prototype.Selector.select(expressions, element);
2236
- },
2237
-
2238
- adjacent: function(element) {
2239
- element = $(element);
2240
- var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2241
- return Prototype.Selector.select(expressions, element.parentNode).without(element);
2242
- },
2243
-
2244
- identify: function(element) {
2245
- element = $(element);
2246
- var id = Element.readAttribute(element, 'id');
2247
- if (id) return id;
2248
- do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
2249
- Element.writeAttribute(element, 'id', id);
2250
- return id;
2251
- },
2252
-
2253
- readAttribute: function(element, name) {
2254
- element = $(element);
2255
- if (Prototype.Browser.IE) {
2256
- var t = Element._attributeTranslations.read;
2257
- if (t.values[name]) return t.values[name](element, name);
2258
- if (t.names[name]) name = t.names[name];
2259
- if (name.include(':')) {
2260
- return (!element.attributes || !element.attributes[name]) ? null :
2261
- element.attributes[name].value;
2262
- }
2263
- }
2264
- return element.getAttribute(name);
2265
- },
2266
-
2267
- writeAttribute: function(element, name, value) {
2268
- element = $(element);
2269
- var attributes = { }, t = Element._attributeTranslations.write;
2270
-
2271
- if (typeof name == 'object') attributes = name;
2272
- else attributes[name] = Object.isUndefined(value) ? true : value;
2273
-
2274
- for (var attr in attributes) {
2275
- name = t.names[attr] || attr;
2276
- value = attributes[attr];
2277
- if (t.values[attr]) name = t.values[attr](element, value);
2278
- if (value === false || value === null)
2279
- element.removeAttribute(name);
2280
- else if (value === true)
2281
- element.setAttribute(name, name);
2282
- else element.setAttribute(name, value);
2283
- }
2284
- return element;
2285
- },
2286
-
2287
- getHeight: function(element) {
2288
- return Element.getDimensions(element).height;
2289
- },
2290
-
2291
- getWidth: function(element) {
2292
- return Element.getDimensions(element).width;
2293
- },
2294
-
2295
- classNames: function(element) {
2296
- return new Element.ClassNames(element);
2297
- },
2298
-
2299
- hasClassName: function(element, className) {
2300
- if (!(element = $(element))) return;
2301
- var elementClassName = element.className;
2302
- return (elementClassName.length > 0 && (elementClassName == className ||
2303
- new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
2304
- },
2305
-
2306
- addClassName: function(element, className) {
2307
- if (!(element = $(element))) return;
2308
- if (!Element.hasClassName(element, className))
2309
- element.className += (element.className ? ' ' : '') + className;
2310
- return element;
2311
- },
2312
-
2313
- removeClassName: function(element, className) {
2314
- if (!(element = $(element))) return;
2315
- element.className = element.className.replace(
2316
- new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
2317
- return element;
2318
- },
2319
-
2320
- toggleClassName: function(element, className) {
2321
- if (!(element = $(element))) return;
2322
- return Element[Element.hasClassName(element, className) ?
2323
- 'removeClassName' : 'addClassName'](element, className);
2324
- },
2325
-
2326
- cleanWhitespace: function(element) {
2327
- element = $(element);
2328
- var node = element.firstChild;
2329
- while (node) {
2330
- var nextNode = node.nextSibling;
2331
- if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
2332
- element.removeChild(node);
2333
- node = nextNode;
2334
- }
2335
- return element;
2336
- },
2337
-
2338
- empty: function(element) {
2339
- return $(element).innerHTML.blank();
2340
- },
2341
-
2342
- descendantOf: function(element, ancestor) {
2343
- element = $(element), ancestor = $(ancestor);
2344
-
2345
- if (element.compareDocumentPosition)
2346
- return (element.compareDocumentPosition(ancestor) & 8) === 8;
2347
-
2348
- if (ancestor.contains)
2349
- return ancestor.contains(element) && ancestor !== element;
2350
-
2351
- while (element = element.parentNode)
2352
- if (element == ancestor) return true;
2353
-
2354
- return false;
2355
- },
2356
-
2357
- scrollTo: function(element) {
2358
- element = $(element);
2359
- var pos = Element.cumulativeOffset(element);
2360
- window.scrollTo(pos[0], pos[1]);
2361
- return element;
2362
- },
2363
-
2364
- getStyle: function(element, style) {
2365
- element = $(element);
2366
- style = style == 'float' ? 'cssFloat' : style.camelize();
2367
- var value = element.style[style];
2368
- if (!value || value == 'auto') {
2369
- var css = document.defaultView.getComputedStyle(element, null);
2370
- value = css ? css[style] : null;
2371
- }
2372
- if (style == 'opacity') return value ? parseFloat(value) : 1.0;
2373
- return value == 'auto' ? null : value;
2374
- },
2375
-
2376
- getOpacity: function(element) {
2377
- return $(element).getStyle('opacity');
2378
- },
2379
-
2380
- setStyle: function(element, styles) {
2381
- element = $(element);
2382
- var elementStyle = element.style, match;
2383
- if (Object.isString(styles)) {
2384
- element.style.cssText += ';' + styles;
2385
- return styles.include('opacity') ?
2386
- element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
2387
- }
2388
- for (var property in styles)
2389
- if (property == 'opacity') element.setOpacity(styles[property]);
2390
- else
2391
- elementStyle[(property == 'float' || property == 'cssFloat') ?
2392
- (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
2393
- property] = styles[property];
2394
-
2395
- return element;
2396
- },
2397
-
2398
- setOpacity: function(element, value) {
2399
- element = $(element);
2400
- element.style.opacity = (value == 1 || value === '') ? '' :
2401
- (value < 0.00001) ? 0 : value;
2402
- return element;
2403
- },
2404
-
2405
- makePositioned: function(element) {
2406
- element = $(element);
2407
- var pos = Element.getStyle(element, 'position');
2408
- if (pos == 'static' || !pos) {
2409
- element._madePositioned = true;
2410
- element.style.position = 'relative';
2411
- if (Prototype.Browser.Opera) {
2412
- element.style.top = 0;
2413
- element.style.left = 0;
2414
- }
2415
- }
2416
- return element;
2417
- },
2418
-
2419
- undoPositioned: function(element) {
2420
- element = $(element);
2421
- if (element._madePositioned) {
2422
- element._madePositioned = undefined;
2423
- element.style.position =
2424
- element.style.top =
2425
- element.style.left =
2426
- element.style.bottom =
2427
- element.style.right = '';
2428
- }
2429
- return element;
2430
- },
2431
-
2432
- makeClipping: function(element) {
2433
- element = $(element);
2434
- if (element._overflow) return element;
2435
- element._overflow = Element.getStyle(element, 'overflow') || 'auto';
2436
- if (element._overflow !== 'hidden')
2437
- element.style.overflow = 'hidden';
2438
- return element;
2439
- },
2440
-
2441
- undoClipping: function(element) {
2442
- element = $(element);
2443
- if (!element._overflow) return element;
2444
- element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
2445
- element._overflow = null;
2446
- return element;
2447
- },
2448
-
2449
- clonePosition: function(element, source) {
2450
- var options = Object.extend({
2451
- setLeft: true,
2452
- setTop: true,
2453
- setWidth: true,
2454
- setHeight: true,
2455
- offsetTop: 0,
2456
- offsetLeft: 0
2457
- }, arguments[2] || { });
2458
-
2459
- source = $(source);
2460
- var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
2461
-
2462
- element = $(element);
2463
-
2464
- if (Element.getStyle(element, 'position') == 'absolute') {
2465
- parent = Element.getOffsetParent(element);
2466
- delta = Element.viewportOffset(parent);
2467
- }
2468
-
2469
- if (parent == document.body) {
2470
- delta[0] -= document.body.offsetLeft;
2471
- delta[1] -= document.body.offsetTop;
2472
- }
2473
-
2474
- if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
2475
- if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
2476
- if (options.setWidth) element.style.width = source.offsetWidth + 'px';
2477
- if (options.setHeight) element.style.height = source.offsetHeight + 'px';
2478
- return element;
2479
- }
2480
- };
2481
-
2482
- Object.extend(Element.Methods, {
2483
- getElementsBySelector: Element.Methods.select,
2484
-
2485
- childElements: Element.Methods.immediateDescendants
2486
- });
2487
-
2488
- Element._attributeTranslations = {
2489
- write: {
2490
- names: {
2491
- className: 'class',
2492
- htmlFor: 'for'
2493
- },
2494
- values: { }
2495
- }
2496
- };
2497
-
2498
- if (Prototype.Browser.Opera) {
2499
- Element.Methods.getStyle = Element.Methods.getStyle.wrap(
2500
- function(proceed, element, style) {
2501
- switch (style) {
2502
- case 'height': case 'width':
2503
- if (!Element.visible(element)) return null;
2504
-
2505
- var dim = parseInt(proceed(element, style), 10);
2506
-
2507
- if (dim !== element['offset' + style.capitalize()])
2508
- return dim + 'px';
2509
-
2510
- var properties;
2511
- if (style === 'height') {
2512
- properties = ['border-top-width', 'padding-top',
2513
- 'padding-bottom', 'border-bottom-width'];
2514
- }
2515
- else {
2516
- properties = ['border-left-width', 'padding-left',
2517
- 'padding-right', 'border-right-width'];
2518
- }
2519
- return properties.inject(dim, function(memo, property) {
2520
- var val = proceed(element, property);
2521
- return val === null ? memo : memo - parseInt(val, 10);
2522
- }) + 'px';
2523
- default: return proceed(element, style);
2524
- }
2525
- }
2526
- );
2527
-
2528
- Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
2529
- function(proceed, element, attribute) {
2530
- if (attribute === 'title') return element.title;
2531
- return proceed(element, attribute);
2532
- }
2533
- );
2534
- }
2535
-
2536
- else if (Prototype.Browser.IE) {
2537
- Element.Methods.getStyle = function(element, style) {
2538
- element = $(element);
2539
- style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
2540
- var value = element.style[style];
2541
- if (!value && element.currentStyle) value = element.currentStyle[style];
2542
-
2543
- if (style == 'opacity') {
2544
- if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
2545
- if (value[1]) return parseFloat(value[1]) / 100;
2546
- return 1.0;
2547
- }
2548
-
2549
- if (value == 'auto') {
2550
- if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
2551
- return element['offset' + style.capitalize()] + 'px';
2552
- return null;
2553
- }
2554
- return value;
2555
- };
2556
-
2557
- Element.Methods.setOpacity = function(element, value) {
2558
- function stripAlpha(filter){
2559
- return filter.replace(/alpha\([^\)]*\)/gi,'');
2560
- }
2561
- element = $(element);
2562
- var currentStyle = element.currentStyle;
2563
- if ((currentStyle && !currentStyle.hasLayout) ||
2564
- (!currentStyle && element.style.zoom == 'normal'))
2565
- element.style.zoom = 1;
2566
-
2567
- var filter = element.getStyle('filter'), style = element.style;
2568
- if (value == 1 || value === '') {
2569
- (filter = stripAlpha(filter)) ?
2570
- style.filter = filter : style.removeAttribute('filter');
2571
- return element;
2572
- } else if (value < 0.00001) value = 0;
2573
- style.filter = stripAlpha(filter) +
2574
- 'alpha(opacity=' + (value * 100) + ')';
2575
- return element;
2576
- };
2577
-
2578
- Element._attributeTranslations = (function(){
2579
-
2580
- var classProp = 'className',
2581
- forProp = 'for',
2582
- el = document.createElement('div');
2583
-
2584
- el.setAttribute(classProp, 'x');
2585
-
2586
- if (el.className !== 'x') {
2587
- el.setAttribute('class', 'x');
2588
- if (el.className === 'x') {
2589
- classProp = 'class';
2590
- }
2591
- }
2592
- el = null;
2593
-
2594
- el = document.createElement('label');
2595
- el.setAttribute(forProp, 'x');
2596
- if (el.htmlFor !== 'x') {
2597
- el.setAttribute('htmlFor', 'x');
2598
- if (el.htmlFor === 'x') {
2599
- forProp = 'htmlFor';
2600
- }
2601
- }
2602
- el = null;
2603
-
2604
- return {
2605
- read: {
2606
- names: {
2607
- 'class': classProp,
2608
- 'className': classProp,
2609
- 'for': forProp,
2610
- 'htmlFor': forProp
2611
- },
2612
- values: {
2613
- _getAttr: function(element, attribute) {
2614
- return element.getAttribute(attribute);
2615
- },
2616
- _getAttr2: function(element, attribute) {
2617
- return element.getAttribute(attribute, 2);
2618
- },
2619
- _getAttrNode: function(element, attribute) {
2620
- var node = element.getAttributeNode(attribute);
2621
- return node ? node.value : "";
2622
- },
2623
- _getEv: (function(){
2624
-
2625
- var el = document.createElement('div'), f;
2626
- el.onclick = Prototype.emptyFunction;
2627
- var value = el.getAttribute('onclick');
2628
-
2629
- if (String(value).indexOf('{') > -1) {
2630
- f = function(element, attribute) {
2631
- attribute = element.getAttribute(attribute);
2632
- if (!attribute) return null;
2633
- attribute = attribute.toString();
2634
- attribute = attribute.split('{')[1];
2635
- attribute = attribute.split('}')[0];
2636
- return attribute.strip();
2637
- };
2638
- }
2639
- else if (value === '') {
2640
- f = function(element, attribute) {
2641
- attribute = element.getAttribute(attribute);
2642
- if (!attribute) return null;
2643
- return attribute.strip();
2644
- };
2645
- }
2646
- el = null;
2647
- return f;
2648
- })(),
2649
- _flag: function(element, attribute) {
2650
- return $(element).hasAttribute(attribute) ? attribute : null;
2651
- },
2652
- style: function(element) {
2653
- return element.style.cssText.toLowerCase();
2654
- },
2655
- title: function(element) {
2656
- return element.title;
2657
- }
2658
- }
2659
- }
2660
- }
2661
- })();
2662
-
2663
- Element._attributeTranslations.write = {
2664
- names: Object.extend({
2665
- cellpadding: 'cellPadding',
2666
- cellspacing: 'cellSpacing'
2667
- }, Element._attributeTranslations.read.names),
2668
- values: {
2669
- checked: function(element, value) {
2670
- element.checked = !!value;
2671
- },
2672
-
2673
- style: function(element, value) {
2674
- element.style.cssText = value ? value : '';
2675
- }
2676
- }
2677
- };
2678
-
2679
- Element._attributeTranslations.has = {};
2680
-
2681
- $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
2682
- 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
2683
- Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
2684
- Element._attributeTranslations.has[attr.toLowerCase()] = attr;
2685
- });
2686
-
2687
- (function(v) {
2688
- Object.extend(v, {
2689
- href: v._getAttr2,
2690
- src: v._getAttr2,
2691
- type: v._getAttr,
2692
- action: v._getAttrNode,
2693
- disabled: v._flag,
2694
- checked: v._flag,
2695
- readonly: v._flag,
2696
- multiple: v._flag,
2697
- onload: v._getEv,
2698
- onunload: v._getEv,
2699
- onclick: v._getEv,
2700
- ondblclick: v._getEv,
2701
- onmousedown: v._getEv,
2702
- onmouseup: v._getEv,
2703
- onmouseover: v._getEv,
2704
- onmousemove: v._getEv,
2705
- onmouseout: v._getEv,
2706
- onfocus: v._getEv,
2707
- onblur: v._getEv,
2708
- onkeypress: v._getEv,
2709
- onkeydown: v._getEv,
2710
- onkeyup: v._getEv,
2711
- onsubmit: v._getEv,
2712
- onreset: v._getEv,
2713
- onselect: v._getEv,
2714
- onchange: v._getEv
2715
- });
2716
- })(Element._attributeTranslations.read.values);
2717
-
2718
- if (Prototype.BrowserFeatures.ElementExtensions) {
2719
- (function() {
2720
- function _descendants(element) {
2721
- var nodes = element.getElementsByTagName('*'), results = [];
2722
- for (var i = 0, node; node = nodes[i]; i++)
2723
- if (node.tagName !== "!") // Filter out comment nodes.
2724
- results.push(node);
2725
- return results;
2726
- }
2727
-
2728
- Element.Methods.down = function(element, expression, index) {
2729
- element = $(element);
2730
- if (arguments.length == 1) return element.firstDescendant();
2731
- return Object.isNumber(expression) ? _descendants(element)[expression] :
2732
- Element.select(element, expression)[index || 0];
2733
- }
2734
- })();
2735
- }
2736
-
2737
- }
2738
-
2739
- else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
2740
- Element.Methods.setOpacity = function(element, value) {
2741
- element = $(element);
2742
- element.style.opacity = (value == 1) ? 0.999999 :
2743
- (value === '') ? '' : (value < 0.00001) ? 0 : value;
2744
- return element;
2745
- };
2746
- }
2747
-
2748
- else if (Prototype.Browser.WebKit) {
2749
- Element.Methods.setOpacity = function(element, value) {
2750
- element = $(element);
2751
- element.style.opacity = (value == 1 || value === '') ? '' :
2752
- (value < 0.00001) ? 0 : value;
2753
-
2754
- if (value == 1)
2755
- if (element.tagName.toUpperCase() == 'IMG' && element.width) {
2756
- element.width++; element.width--;
2757
- } else try {
2758
- var n = document.createTextNode(' ');
2759
- element.appendChild(n);
2760
- element.removeChild(n);
2761
- } catch (e) { }
2762
-
2763
- return element;
2764
- };
2765
- }
2766
-
2767
- if ('outerHTML' in document.documentElement) {
2768
- Element.Methods.replace = function(element, content) {
2769
- element = $(element);
2770
-
2771
- if (content && content.toElement) content = content.toElement();
2772
- if (Object.isElement(content)) {
2773
- element.parentNode.replaceChild(content, element);
2774
- return element;
2775
- }
2776
-
2777
- content = Object.toHTML(content);
2778
- var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2779
-
2780
- if (Element._insertionTranslations.tags[tagName]) {
2781
- var nextSibling = element.next(),
2782
- fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2783
- parent.removeChild(element);
2784
- if (nextSibling)
2785
- fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
2786
- else
2787
- fragments.each(function(node) { parent.appendChild(node) });
2788
- }
2789
- else element.outerHTML = content.stripScripts();
2790
-
2791
- content.evalScripts.bind(content).defer();
2792
- return element;
2793
- };
2794
- }
2795
-
2796
- Element._returnOffset = function(l, t) {
2797
- var result = [l, t];
2798
- result.left = l;
2799
- result.top = t;
2800
- return result;
2801
- };
2802
-
2803
- Element._getContentFromAnonymousElement = function(tagName, html, force) {
2804
- var div = new Element('div'),
2805
- t = Element._insertionTranslations.tags[tagName];
2806
-
2807
- var workaround = false;
2808
- if (t) workaround = true;
2809
- else if (force) {
2810
- workaround = true;
2811
- t = ['', '', 0];
2812
- }
2813
-
2814
- if (workaround) {
2815
- div.innerHTML = '&nbsp;' + t[0] + html + t[1];
2816
- div.removeChild(div.firstChild);
2817
- for (var i = t[2]; i--; ) {
2818
- div = div.firstChild;
2819
- }
2820
- }
2821
- else {
2822
- div.innerHTML = html;
2823
- }
2824
- return $A(div.childNodes);
2825
- };
2826
-
2827
- Element._insertionTranslations = {
2828
- before: function(element, node) {
2829
- element.parentNode.insertBefore(node, element);
2830
- },
2831
- top: function(element, node) {
2832
- element.insertBefore(node, element.firstChild);
2833
- },
2834
- bottom: function(element, node) {
2835
- element.appendChild(node);
2836
- },
2837
- after: function(element, node) {
2838
- element.parentNode.insertBefore(node, element.nextSibling);
2839
- },
2840
- tags: {
2841
- TABLE: ['<table>', '</table>', 1],
2842
- TBODY: ['<table><tbody>', '</tbody></table>', 2],
2843
- TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
2844
- TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2845
- SELECT: ['<select>', '</select>', 1]
2846
- }
2847
- };
2848
-
2849
- (function() {
2850
- var tags = Element._insertionTranslations.tags;
2851
- Object.extend(tags, {
2852
- THEAD: tags.TBODY,
2853
- TFOOT: tags.TBODY,
2854
- TH: tags.TD
2855
- });
2856
- })();
2857
-
2858
- Element.Methods.Simulated = {
2859
- hasAttribute: function(element, attribute) {
2860
- attribute = Element._attributeTranslations.has[attribute] || attribute;
2861
- var node = $(element).getAttributeNode(attribute);
2862
- return !!(node && node.specified);
2863
- }
2864
- };
2865
-
2866
- Element.Methods.ByTag = { };
2867
-
2868
- Object.extend(Element, Element.Methods);
2869
-
2870
- (function(div) {
2871
-
2872
- if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
2873
- window.HTMLElement = { };
2874
- window.HTMLElement.prototype = div['__proto__'];
2875
- Prototype.BrowserFeatures.ElementExtensions = true;
2876
- }
2877
-
2878
- div = null;
2879
-
2880
- })(document.createElement('div'));
2881
-
2882
- Element.extend = (function() {
2883
-
2884
- function checkDeficiency(tagName) {
2885
- if (typeof window.Element != 'undefined') {
2886
- var proto = window.Element.prototype;
2887
- if (proto) {
2888
- var id = '_' + (Math.random()+'').slice(2),
2889
- el = document.createElement(tagName);
2890
- proto[id] = 'x';
2891
- var isBuggy = (el[id] !== 'x');
2892
- delete proto[id];
2893
- el = null;
2894
- return isBuggy;
2895
- }
2896
- }
2897
- return false;
2898
- }
2899
-
2900
- function extendElementWith(element, methods) {
2901
- for (var property in methods) {
2902
- var value = methods[property];
2903
- if (Object.isFunction(value) && !(property in element))
2904
- element[property] = value.methodize();
2905
- }
2906
- }
2907
-
2908
- var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
2909
-
2910
- if (Prototype.BrowserFeatures.SpecificElementExtensions) {
2911
- if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
2912
- return function(element) {
2913
- if (element && typeof element._extendedByPrototype == 'undefined') {
2914
- var t = element.tagName;
2915
- if (t && (/^(?:object|applet|embed)$/i.test(t))) {
2916
- extendElementWith(element, Element.Methods);
2917
- extendElementWith(element, Element.Methods.Simulated);
2918
- extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
2919
- }
2920
- }
2921
- return element;
2922
- }
2923
- }
2924
- return Prototype.K;
2925
- }
2926
-
2927
- var Methods = { }, ByTag = Element.Methods.ByTag;
2928
-
2929
- var extend = Object.extend(function(element) {
2930
- if (!element || typeof element._extendedByPrototype != 'undefined' ||
2931
- element.nodeType != 1 || element == window) return element;
2932
-
2933
- var methods = Object.clone(Methods),
2934
- tagName = element.tagName.toUpperCase();
2935
-
2936
- if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
2937
-
2938
- extendElementWith(element, methods);
2939
-
2940
- element._extendedByPrototype = Prototype.emptyFunction;
2941
- return element;
2942
-
2943
- }, {
2944
- refresh: function() {
2945
- if (!Prototype.BrowserFeatures.ElementExtensions) {
2946
- Object.extend(Methods, Element.Methods);
2947
- Object.extend(Methods, Element.Methods.Simulated);
2948
- }
2949
- }
2950
- });
2951
-
2952
- extend.refresh();
2953
- return extend;
2954
- })();
2955
-
2956
- if (document.documentElement.hasAttribute) {
2957
- Element.hasAttribute = function(element, attribute) {
2958
- return element.hasAttribute(attribute);
2959
- };
2960
- }
2961
- else {
2962
- Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
2963
- }
2964
-
2965
- Element.addMethods = function(methods) {
2966
- var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
2967
-
2968
- if (!methods) {
2969
- Object.extend(Form, Form.Methods);
2970
- Object.extend(Form.Element, Form.Element.Methods);
2971
- Object.extend(Element.Methods.ByTag, {
2972
- "FORM": Object.clone(Form.Methods),
2973
- "INPUT": Object.clone(Form.Element.Methods),
2974
- "SELECT": Object.clone(Form.Element.Methods),
2975
- "TEXTAREA": Object.clone(Form.Element.Methods),
2976
- "BUTTON": Object.clone(Form.Element.Methods)
2977
- });
2978
- }
2979
-
2980
- if (arguments.length == 2) {
2981
- var tagName = methods;
2982
- methods = arguments[1];
2983
- }
2984
-
2985
- if (!tagName) Object.extend(Element.Methods, methods || { });
2986
- else {
2987
- if (Object.isArray(tagName)) tagName.each(extend);
2988
- else extend(tagName);
2989
- }
2990
-
2991
- function extend(tagName) {
2992
- tagName = tagName.toUpperCase();
2993
- if (!Element.Methods.ByTag[tagName])
2994
- Element.Methods.ByTag[tagName] = { };
2995
- Object.extend(Element.Methods.ByTag[tagName], methods);
2996
- }
2997
-
2998
- function copy(methods, destination, onlyIfAbsent) {
2999
- onlyIfAbsent = onlyIfAbsent || false;
3000
- for (var property in methods) {
3001
- var value = methods[property];
3002
- if (!Object.isFunction(value)) continue;
3003
- if (!onlyIfAbsent || !(property in destination))
3004
- destination[property] = value.methodize();
3005
- }
3006
- }
3007
-
3008
- function findDOMClass(tagName) {
3009
- var klass;
3010
- var trans = {
3011
- "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
3012
- "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
3013
- "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
3014
- "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
3015
- "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
3016
- "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
3017
- "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
3018
- "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
3019
- "FrameSet", "IFRAME": "IFrame"
3020
- };
3021
- if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
3022
- if (window[klass]) return window[klass];
3023
- klass = 'HTML' + tagName + 'Element';
3024
- if (window[klass]) return window[klass];
3025
- klass = 'HTML' + tagName.capitalize() + 'Element';
3026
- if (window[klass]) return window[klass];
3027
-
3028
- var element = document.createElement(tagName),
3029
- proto = element['__proto__'] || element.constructor.prototype;
3030
-
3031
- element = null;
3032
- return proto;
3033
- }
3034
-
3035
- var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
3036
- Element.prototype;
3037
-
3038
- if (F.ElementExtensions) {
3039
- copy(Element.Methods, elementPrototype);
3040
- copy(Element.Methods.Simulated, elementPrototype, true);
3041
- }
3042
-
3043
- if (F.SpecificElementExtensions) {
3044
- for (var tag in Element.Methods.ByTag) {
3045
- var klass = findDOMClass(tag);
3046
- if (Object.isUndefined(klass)) continue;
3047
- copy(T[tag], klass.prototype);
3048
- }
3049
- }
3050
-
3051
- Object.extend(Element, Element.Methods);
3052
- delete Element.ByTag;
3053
-
3054
- if (Element.extend.refresh) Element.extend.refresh();
3055
- Element.cache = { };
3056
- };
3057
-
3058
-
3059
- document.viewport = {
3060
-
3061
- getDimensions: function() {
3062
- return { width: this.getWidth(), height: this.getHeight() };
3063
- },
3064
-
3065
- getScrollOffsets: function() {
3066
- return Element._returnOffset(
3067
- window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
3068
- window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
3069
- }
3070
- };
3071
-
3072
- (function(viewport) {
3073
- var B = Prototype.Browser, doc = document, element, property = {};
3074
-
3075
- function getRootElement() {
3076
- if (B.WebKit && !doc.evaluate)
3077
- return document;
3078
-
3079
- if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
3080
- return document.body;
3081
-
3082
- return document.documentElement;
3083
- }
3084
-
3085
- function define(D) {
3086
- if (!element) element = getRootElement();
3087
-
3088
- property[D] = 'client' + D;
3089
-
3090
- viewport['get' + D] = function() { return element[property[D]] };
3091
- return viewport['get' + D]();
3092
- }
3093
-
3094
- viewport.getWidth = define.curry('Width');
3095
-
3096
- viewport.getHeight = define.curry('Height');
3097
- })(document.viewport);
3098
-
3099
-
3100
- Element.Storage = {
3101
- UID: 1
3102
- };
3103
-
3104
- Element.addMethods({
3105
- getStorage: function(element) {
3106
- if (!(element = $(element))) return;
3107
-
3108
- var uid;
3109
- if (element === window) {
3110
- uid = 0;
3111
- } else {
3112
- if (typeof element._prototypeUID === "undefined")
3113
- element._prototypeUID = Element.Storage.UID++;
3114
- uid = element._prototypeUID;
3115
- }
3116
-
3117
- if (!Element.Storage[uid])
3118
- Element.Storage[uid] = $H();
3119
-
3120
- return Element.Storage[uid];
3121
- },
3122
-
3123
- store: function(element, key, value) {
3124
- if (!(element = $(element))) return;
3125
-
3126
- if (arguments.length === 2) {
3127
- Element.getStorage(element).update(key);
3128
- } else {
3129
- Element.getStorage(element).set(key, value);
3130
- }
3131
-
3132
- return element;
3133
- },
3134
-
3135
- retrieve: function(element, key, defaultValue) {
3136
- if (!(element = $(element))) return;
3137
- var hash = Element.getStorage(element), value = hash.get(key);
3138
-
3139
- if (Object.isUndefined(value)) {
3140
- hash.set(key, defaultValue);
3141
- value = defaultValue;
3142
- }
3143
-
3144
- return value;
3145
- },
3146
-
3147
- clone: function(element, deep) {
3148
- if (!(element = $(element))) return;
3149
- var clone = element.cloneNode(deep);
3150
- clone._prototypeUID = void 0;
3151
- if (deep) {
3152
- var descendants = Element.select(clone, '*'),
3153
- i = descendants.length;
3154
- while (i--) {
3155
- descendants[i]._prototypeUID = void 0;
3156
- }
3157
- }
3158
- return Element.extend(clone);
3159
- },
3160
-
3161
- purge: function(element) {
3162
- if (!(element = $(element))) return;
3163
- var purgeElement = Element._purgeElement;
3164
-
3165
- purgeElement(element);
3166
-
3167
- var descendants = element.getElementsByTagName('*'),
3168
- i = descendants.length;
3169
-
3170
- while (i--) purgeElement(descendants[i]);
3171
-
3172
- return null;
3173
- }
3174
- });
3175
-
3176
- (function() {
3177
-
3178
- function toDecimal(pctString) {
3179
- var match = pctString.match(/^(\d+)%?$/i);
3180
- if (!match) return null;
3181
- return (Number(match[1]) / 100);
3182
- }
3183
-
3184
- function getPixelValue(value, property, context) {
3185
- var element = null;
3186
- if (Object.isElement(value)) {
3187
- element = value;
3188
- value = element.getStyle(property);
3189
- }
3190
-
3191
- if (value === null) {
3192
- return null;
3193
- }
3194
-
3195
- if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3196
- return window.parseFloat(value);
3197
- }
3198
-
3199
- var isPercentage = value.include('%'), isViewport = (context === document.viewport);
3200
-
3201
- if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3202
- var style = element.style.left, rStyle = element.runtimeStyle.left;
3203
- element.runtimeStyle.left = element.currentStyle.left;
3204
- element.style.left = value || 0;
3205
- value = element.style.pixelLeft;
3206
- element.style.left = style;
3207
- element.runtimeStyle.left = rStyle;
3208
-
3209
- return value;
3210
- }
3211
-
3212
- if (element && isPercentage) {
3213
- context = context || element.parentNode;
3214
- var decimal = toDecimal(value);
3215
- var whole = null;
3216
- var position = element.getStyle('position');
3217
-
3218
- var isHorizontal = property.include('left') || property.include('right') ||
3219
- property.include('width');
3220
-
3221
- var isVertical = property.include('top') || property.include('bottom') ||
3222
- property.include('height');
3223
-
3224
- if (context === document.viewport) {
3225
- if (isHorizontal) {
3226
- whole = document.viewport.getWidth();
3227
- } else if (isVertical) {
3228
- whole = document.viewport.getHeight();
3229
- }
3230
- } else {
3231
- if (isHorizontal) {
3232
- whole = $(context).measure('width');
3233
- } else if (isVertical) {
3234
- whole = $(context).measure('height');
3235
- }
3236
- }
3237
-
3238
- return (whole === null) ? 0 : whole * decimal;
3239
- }
3240
-
3241
- return 0;
3242
- }
3243
-
3244
- function toCSSPixels(number) {
3245
- if (Object.isString(number) && number.endsWith('px')) {
3246
- return number;
3247
- }
3248
- return number + 'px';
3249
- }
3250
-
3251
- function isDisplayed(element) {
3252
- var originalElement = element;
3253
- while (element && element.parentNode) {
3254
- var display = element.getStyle('display');
3255
- if (display === 'none') {
3256
- return false;
3257
- }
3258
- element = $(element.parentNode);
3259
- }
3260
- return true;
3261
- }
3262
-
3263
- var hasLayout = Prototype.K;
3264
- if ('currentStyle' in document.documentElement) {
3265
- hasLayout = function(element) {
3266
- if (!element.currentStyle.hasLayout) {
3267
- element.style.zoom = 1;
3268
- }
3269
- return element;
3270
- };
3271
- }
3272
-
3273
- function cssNameFor(key) {
3274
- if (key.include('border')) key = key + '-width';
3275
- return key.camelize();
3276
- }
3277
-
3278
- Element.Layout = Class.create(Hash, {
3279
- initialize: function($super, element, preCompute) {
3280
- $super();
3281
- this.element = $(element);
3282
-
3283
- Element.Layout.PROPERTIES.each( function(property) {
3284
- this._set(property, null);
3285
- }, this);
3286
-
3287
- if (preCompute) {
3288
- this._preComputing = true;
3289
- this._begin();
3290
- Element.Layout.PROPERTIES.each( this._compute, this );
3291
- this._end();
3292
- this._preComputing = false;
3293
- }
3294
- },
3295
-
3296
- _set: function(property, value) {
3297
- return Hash.prototype.set.call(this, property, value);
3298
- },
3299
-
3300
- set: function(property, value) {
3301
- throw "Properties of Element.Layout are read-only.";
3302
- },
3303
-
3304
- get: function($super, property) {
3305
- var value = $super(property);
3306
- return value === null ? this._compute(property) : value;
3307
- },
3308
-
3309
- _begin: function() {
3310
- if (this._prepared) return;
3311
-
3312
- var element = this.element;
3313
- if (isDisplayed(element)) {
3314
- this._prepared = true;
3315
- return;
3316
- }
3317
-
3318
- var originalStyles = {
3319
- position: element.style.position || '',
3320
- width: element.style.width || '',
3321
- visibility: element.style.visibility || '',
3322
- display: element.style.display || ''
3323
- };
3324
-
3325
- element.store('prototype_original_styles', originalStyles);
3326
-
3327
- var position = element.getStyle('position'),
3328
- width = element.getStyle('width');
3329
-
3330
- if (width === "0px" || width === null) {
3331
- element.style.display = 'block';
3332
- width = element.getStyle('width');
3333
- }
3334
-
3335
- var context = (position === 'fixed') ? document.viewport :
3336
- element.parentNode;
3337
-
3338
- element.setStyle({
3339
- position: 'absolute',
3340
- visibility: 'hidden',
3341
- display: 'block'
3342
- });
3343
-
3344
- var positionedWidth = element.getStyle('width');
3345
-
3346
- var newWidth;
3347
- if (width && (positionedWidth === width)) {
3348
- newWidth = getPixelValue(element, 'width', context);
3349
- } else if (position === 'absolute' || position === 'fixed') {
3350
- newWidth = getPixelValue(element, 'width', context);
3351
- } else {
3352
- var parent = element.parentNode, pLayout = $(parent).getLayout();
3353
-
3354
- newWidth = pLayout.get('width') -
3355
- this.get('margin-left') -
3356
- this.get('border-left') -
3357
- this.get('padding-left') -
3358
- this.get('padding-right') -
3359
- this.get('border-right') -
3360
- this.get('margin-right');
3361
- }
3362
-
3363
- element.setStyle({ width: newWidth + 'px' });
3364
-
3365
- this._prepared = true;
3366
- },
3367
-
3368
- _end: function() {
3369
- var element = this.element;
3370
- var originalStyles = element.retrieve('prototype_original_styles');
3371
- element.store('prototype_original_styles', null);
3372
- element.setStyle(originalStyles);
3373
- this._prepared = false;
3374
- },
3375
-
3376
- _compute: function(property) {
3377
- var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3378
- if (!(property in COMPUTATIONS)) {
3379
- throw "Property not found.";
3380
- }
3381
-
3382
- return this._set(property, COMPUTATIONS[property].call(this, this.element));
3383
- },
3384
-
3385
- toObject: function() {
3386
- var args = $A(arguments);
3387
- var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3388
- args.join(' ').split(' ');
3389
- var obj = {};
3390
- keys.each( function(key) {
3391
- if (!Element.Layout.PROPERTIES.include(key)) return;
3392
- var value = this.get(key);
3393
- if (value != null) obj[key] = value;
3394
- }, this);
3395
- return obj;
3396
- },
3397
-
3398
- toHash: function() {
3399
- var obj = this.toObject.apply(this, arguments);
3400
- return new Hash(obj);
3401
- },
3402
-
3403
- toCSS: function() {
3404
- var args = $A(arguments);
3405
- var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3406
- args.join(' ').split(' ');
3407
- var css = {};
3408
-
3409
- keys.each( function(key) {
3410
- if (!Element.Layout.PROPERTIES.include(key)) return;
3411
- if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3412
-
3413
- var value = this.get(key);
3414
- if (value != null) css[cssNameFor(key)] = value + 'px';
3415
- }, this);
3416
- return css;
3417
- },
3418
-
3419
- inspect: function() {
3420
- return "#<Element.Layout>";
3421
- }
3422
- });
3423
-
3424
- Object.extend(Element.Layout, {
3425
- PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3426
-
3427
- COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3428
-
3429
- COMPUTATIONS: {
3430
- 'height': function(element) {
3431
- if (!this._preComputing) this._begin();
3432
-
3433
- var bHeight = this.get('border-box-height');
3434
- if (bHeight <= 0) {
3435
- if (!this._preComputing) this._end();
3436
- return 0;
3437
- }
3438
-
3439
- var bTop = this.get('border-top'),
3440
- bBottom = this.get('border-bottom');
3441
-
3442
- var pTop = this.get('padding-top'),
3443
- pBottom = this.get('padding-bottom');
3444
-
3445
- if (!this._preComputing) this._end();
3446
-
3447
- return bHeight - bTop - bBottom - pTop - pBottom;
3448
- },
3449
-
3450
- 'width': function(element) {
3451
- if (!this._preComputing) this._begin();
3452
-
3453
- var bWidth = this.get('border-box-width');
3454
- if (bWidth <= 0) {
3455
- if (!this._preComputing) this._end();
3456
- return 0;
3457
- }
3458
-
3459
- var bLeft = this.get('border-left'),
3460
- bRight = this.get('border-right');
3461
-
3462
- var pLeft = this.get('padding-left'),
3463
- pRight = this.get('padding-right');
3464
-
3465
- if (!this._preComputing) this._end();
3466
-
3467
- return bWidth - bLeft - bRight - pLeft - pRight;
3468
- },
3469
-
3470
- 'padding-box-height': function(element) {
3471
- var height = this.get('height'),
3472
- pTop = this.get('padding-top'),
3473
- pBottom = this.get('padding-bottom');
3474
-
3475
- return height + pTop + pBottom;
3476
- },
3477
-
3478
- 'padding-box-width': function(element) {
3479
- var width = this.get('width'),
3480
- pLeft = this.get('padding-left'),
3481
- pRight = this.get('padding-right');
3482
-
3483
- return width + pLeft + pRight;
3484
- },
3485
-
3486
- 'border-box-height': function(element) {
3487
- if (!this._preComputing) this._begin();
3488
- var height = element.offsetHeight;
3489
- if (!this._preComputing) this._end();
3490
- return height;
3491
- },
3492
-
3493
- 'border-box-width': function(element) {
3494
- if (!this._preComputing) this._begin();
3495
- var width = element.offsetWidth;
3496
- if (!this._preComputing) this._end();
3497
- return width;
3498
- },
3499
-
3500
- 'margin-box-height': function(element) {
3501
- var bHeight = this.get('border-box-height'),
3502
- mTop = this.get('margin-top'),
3503
- mBottom = this.get('margin-bottom');
3504
-
3505
- if (bHeight <= 0) return 0;
3506
-
3507
- return bHeight + mTop + mBottom;
3508
- },
3509
-
3510
- 'margin-box-width': function(element) {
3511
- var bWidth = this.get('border-box-width'),
3512
- mLeft = this.get('margin-left'),
3513
- mRight = this.get('margin-right');
3514
-
3515
- if (bWidth <= 0) return 0;
3516
-
3517
- return bWidth + mLeft + mRight;
3518
- },
3519
-
3520
- 'top': function(element) {
3521
- var offset = element.positionedOffset();
3522
- return offset.top;
3523
- },
3524
-
3525
- 'bottom': function(element) {
3526
- var offset = element.positionedOffset(),
3527
- parent = element.getOffsetParent(),
3528
- pHeight = parent.measure('height');
3529
-
3530
- var mHeight = this.get('border-box-height');
3531
-
3532
- return pHeight - mHeight - offset.top;
3533
- },
3534
-
3535
- 'left': function(element) {
3536
- var offset = element.positionedOffset();
3537
- return offset.left;
3538
- },
3539
-
3540
- 'right': function(element) {
3541
- var offset = element.positionedOffset(),
3542
- parent = element.getOffsetParent(),
3543
- pWidth = parent.measure('width');
3544
-
3545
- var mWidth = this.get('border-box-width');
3546
-
3547
- return pWidth - mWidth - offset.left;
3548
- },
3549
-
3550
- 'padding-top': function(element) {
3551
- return getPixelValue(element, 'paddingTop');
3552
- },
3553
-
3554
- 'padding-bottom': function(element) {
3555
- return getPixelValue(element, 'paddingBottom');
3556
- },
3557
-
3558
- 'padding-left': function(element) {
3559
- return getPixelValue(element, 'paddingLeft');
3560
- },
3561
-
3562
- 'padding-right': function(element) {
3563
- return getPixelValue(element, 'paddingRight');
3564
- },
3565
-
3566
- 'border-top': function(element) {
3567
- return getPixelValue(element, 'borderTopWidth');
3568
- },
3569
-
3570
- 'border-bottom': function(element) {
3571
- return getPixelValue(element, 'borderBottomWidth');
3572
- },
3573
-
3574
- 'border-left': function(element) {
3575
- return getPixelValue(element, 'borderLeftWidth');
3576
- },
3577
-
3578
- 'border-right': function(element) {
3579
- return getPixelValue(element, 'borderRightWidth');
3580
- },
3581
-
3582
- 'margin-top': function(element) {
3583
- return getPixelValue(element, 'marginTop');
3584
- },
3585
-
3586
- 'margin-bottom': function(element) {
3587
- return getPixelValue(element, 'marginBottom');
3588
- },
3589
-
3590
- 'margin-left': function(element) {
3591
- return getPixelValue(element, 'marginLeft');
3592
- },
3593
-
3594
- 'margin-right': function(element) {
3595
- return getPixelValue(element, 'marginRight');
3596
- }
3597
- }
3598
- });
3599
-
3600
- if ('getBoundingClientRect' in document.documentElement) {
3601
- Object.extend(Element.Layout.COMPUTATIONS, {
3602
- 'right': function(element) {
3603
- var parent = hasLayout(element.getOffsetParent());
3604
- var rect = element.getBoundingClientRect(),
3605
- pRect = parent.getBoundingClientRect();
3606
-
3607
- return (pRect.right - rect.right).round();
3608
- },
3609
-
3610
- 'bottom': function(element) {
3611
- var parent = hasLayout(element.getOffsetParent());
3612
- var rect = element.getBoundingClientRect(),
3613
- pRect = parent.getBoundingClientRect();
3614
-
3615
- return (pRect.bottom - rect.bottom).round();
3616
- }
3617
- });
3618
- }
3619
-
3620
- Element.Offset = Class.create({
3621
- initialize: function(left, top) {
3622
- this.left = left.round();
3623
- this.top = top.round();
3624
-
3625
- this[0] = this.left;
3626
- this[1] = this.top;
3627
- },
3628
-
3629
- relativeTo: function(offset) {
3630
- return new Element.Offset(
3631
- this.left - offset.left,
3632
- this.top - offset.top
3633
- );
3634
- },
3635
-
3636
- inspect: function() {
3637
- return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3638
- },
3639
-
3640
- toString: function() {
3641
- return "[#{left}, #{top}]".interpolate(this);
3642
- },
3643
-
3644
- toArray: function() {
3645
- return [this.left, this.top];
3646
- }
3647
- });
3648
-
3649
- function getLayout(element, preCompute) {
3650
- return new Element.Layout(element, preCompute);
3651
- }
3652
-
3653
- function measure(element, property) {
3654
- return $(element).getLayout().get(property);
3655
- }
3656
-
3657
- function getDimensions(element) {
3658
- element = $(element);
3659
- var display = Element.getStyle(element, 'display');
3660
-
3661
- if (display && display !== 'none') {
3662
- return { width: element.offsetWidth, height: element.offsetHeight };
3663
- }
3664
-
3665
- var style = element.style;
3666
- var originalStyles = {
3667
- visibility: style.visibility,
3668
- position: style.position,
3669
- display: style.display
3670
- };
3671
-
3672
- var newStyles = {
3673
- visibility: 'hidden',
3674
- display: 'block'
3675
- };
3676
-
3677
- if (originalStyles.position !== 'fixed')
3678
- newStyles.position = 'absolute';
3679
-
3680
- Element.setStyle(element, newStyles);
3681
-
3682
- var dimensions = {
3683
- width: element.offsetWidth,
3684
- height: element.offsetHeight
3685
- };
3686
-
3687
- Element.setStyle(element, originalStyles);
3688
-
3689
- return dimensions;
3690
- }
3691
-
3692
- function getOffsetParent(element) {
3693
- element = $(element);
3694
-
3695
- if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3696
- return $(document.body);
3697
-
3698
- var isInline = (Element.getStyle(element, 'display') === 'inline');
3699
- if (!isInline && element.offsetParent) return $(element.offsetParent);
3700
-
3701
- while ((element = element.parentNode) && element !== document.body) {
3702
- if (Element.getStyle(element, 'position') !== 'static') {
3703
- return isHtml(element) ? $(document.body) : $(element);
3704
- }
3705
- }
3706
-
3707
- return $(document.body);
3708
- }
3709
-
3710
-
3711
- function cumulativeOffset(element) {
3712
- element = $(element);
3713
- var valueT = 0, valueL = 0;
3714
- if (element.parentNode) {
3715
- do {
3716
- valueT += element.offsetTop || 0;
3717
- valueL += element.offsetLeft || 0;
3718
- element = element.offsetParent;
3719
- } while (element);
3720
- }
3721
- return new Element.Offset(valueL, valueT);
3722
- }
3723
-
3724
- function positionedOffset(element) {
3725
- element = $(element);
3726
-
3727
- var layout = element.getLayout();
3728
-
3729
- var valueT = 0, valueL = 0;
3730
- do {
3731
- valueT += element.offsetTop || 0;
3732
- valueL += element.offsetLeft || 0;
3733
- element = element.offsetParent;
3734
- if (element) {
3735
- if (isBody(element)) break;
3736
- var p = Element.getStyle(element, 'position');
3737
- if (p !== 'static') break;
3738
- }
3739
- } while (element);
3740
-
3741
- valueL -= layout.get('margin-top');
3742
- valueT -= layout.get('margin-left');
3743
-
3744
- return new Element.Offset(valueL, valueT);
3745
- }
3746
-
3747
- function cumulativeScrollOffset(element) {
3748
- var valueT = 0, valueL = 0;
3749
- do {
3750
- valueT += element.scrollTop || 0;
3751
- valueL += element.scrollLeft || 0;
3752
- element = element.parentNode;
3753
- } while (element);
3754
- return new Element.Offset(valueL, valueT);
3755
- }
3756
-
3757
- function viewportOffset(forElement) {
3758
- element = $(element);
3759
- var valueT = 0, valueL = 0, docBody = document.body;
3760
-
3761
- var element = forElement;
3762
- do {
3763
- valueT += element.offsetTop || 0;
3764
- valueL += element.offsetLeft || 0;
3765
- if (element.offsetParent == docBody &&
3766
- Element.getStyle(element, 'position') == 'absolute') break;
3767
- } while (element = element.offsetParent);
3768
-
3769
- element = forElement;
3770
- do {
3771
- if (element != docBody) {
3772
- valueT -= element.scrollTop || 0;
3773
- valueL -= element.scrollLeft || 0;
3774
- }
3775
- } while (element = element.parentNode);
3776
- return new Element.Offset(valueL, valueT);
3777
- }
3778
-
3779
- function absolutize(element) {
3780
- element = $(element);
3781
-
3782
- if (Element.getStyle(element, 'position') === 'absolute') {
3783
- return element;
3784
- }
3785
-
3786
- var offsetParent = getOffsetParent(element);
3787
- var eOffset = element.viewportOffset(),
3788
- pOffset = offsetParent.viewportOffset();
3789
-
3790
- var offset = eOffset.relativeTo(pOffset);
3791
- var layout = element.getLayout();
3792
-
3793
- element.store('prototype_absolutize_original_styles', {
3794
- left: element.getStyle('left'),
3795
- top: element.getStyle('top'),
3796
- width: element.getStyle('width'),
3797
- height: element.getStyle('height')
3798
- });
3799
-
3800
- element.setStyle({
3801
- position: 'absolute',
3802
- top: offset.top + 'px',
3803
- left: offset.left + 'px',
3804
- width: layout.get('width') + 'px',
3805
- height: layout.get('height') + 'px'
3806
- });
3807
-
3808
- return element;
3809
- }
3810
-
3811
- function relativize(element) {
3812
- element = $(element);
3813
- if (Element.getStyle(element, 'position') === 'relative') {
3814
- return element;
3815
- }
3816
-
3817
- var originalStyles =
3818
- element.retrieve('prototype_absolutize_original_styles');
3819
-
3820
- if (originalStyles) element.setStyle(originalStyles);
3821
- return element;
3822
- }
3823
-
3824
- if (Prototype.Browser.IE) {
3825
- getOffsetParent = getOffsetParent.wrap(
3826
- function(proceed, element) {
3827
- element = $(element);
3828
-
3829
- if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3830
- return $(document.body);
3831
-
3832
- var position = element.getStyle('position');
3833
- if (position !== 'static') return proceed(element);
3834
-
3835
- element.setStyle({ position: 'relative' });
3836
- var value = proceed(element);
3837
- element.setStyle({ position: position });
3838
- return value;
3839
- }
3840
- );
3841
-
3842
- positionedOffset = positionedOffset.wrap(function(proceed, element) {
3843
- element = $(element);
3844
- if (!element.parentNode) return new Element.Offset(0, 0);
3845
- var position = element.getStyle('position');
3846
- if (position !== 'static') return proceed(element);
3847
-
3848
- var offsetParent = element.getOffsetParent();
3849
- if (offsetParent && offsetParent.getStyle('position') === 'fixed')
3850
- hasLayout(offsetParent);
3851
-
3852
- element.setStyle({ position: 'relative' });
3853
- var value = proceed(element);
3854
- element.setStyle({ position: position });
3855
- return value;
3856
- });
3857
- } else if (Prototype.Browser.Webkit) {
3858
- cumulativeOffset = function(element) {
3859
- element = $(element);
3860
- var valueT = 0, valueL = 0;
3861
- do {
3862
- valueT += element.offsetTop || 0;
3863
- valueL += element.offsetLeft || 0;
3864
- if (element.offsetParent == document.body)
3865
- if (Element.getStyle(element, 'position') == 'absolute') break;
3866
-
3867
- element = element.offsetParent;
3868
- } while (element);
3869
-
3870
- return new Element.Offset(valueL, valueT);
3871
- };
3872
- }
3873
-
3874
-
3875
- Element.addMethods({
3876
- getLayout: getLayout,
3877
- measure: measure,
3878
- getDimensions: getDimensions,
3879
- getOffsetParent: getOffsetParent,
3880
- cumulativeOffset: cumulativeOffset,
3881
- positionedOffset: positionedOffset,
3882
- cumulativeScrollOffset: cumulativeScrollOffset,
3883
- viewportOffset: viewportOffset,
3884
- absolutize: absolutize,
3885
- relativize: relativize
3886
- });
3887
-
3888
- function isBody(element) {
3889
- return element.nodeName.toUpperCase() === 'BODY';
3890
- }
3891
-
3892
- function isHtml(element) {
3893
- return element.nodeName.toUpperCase() === 'HTML';
3894
- }
3895
-
3896
- function isDocument(element) {
3897
- return element.nodeType === Node.DOCUMENT_NODE;
3898
- }
3899
-
3900
- function isDetached(element) {
3901
- return element !== document.body &&
3902
- !Element.descendantOf(element, document.body);
3903
- }
3904
-
3905
- if ('getBoundingClientRect' in document.documentElement) {
3906
- Element.addMethods({
3907
- viewportOffset: function(element) {
3908
- element = $(element);
3909
- if (isDetached(element)) return new Element.Offset(0, 0);
3910
-
3911
- var rect = element.getBoundingClientRect(),
3912
- docEl = document.documentElement;
3913
- return new Element.Offset(rect.left - docEl.clientLeft,
3914
- rect.top - docEl.clientTop);
3915
- }
3916
- });
3917
- }
3918
- })();
3919
- window.$$ = function() {
3920
- var expression = $A(arguments).join(', ');
3921
- return Prototype.Selector.select(expression, document);
3922
- };
3923
-
3924
- Prototype.Selector = (function() {
3925
-
3926
- function select() {
3927
- throw new Error('Method "Prototype.Selector.select" must be defined.');
3928
- }
3929
-
3930
- function match() {
3931
- throw new Error('Method "Prototype.Selector.match" must be defined.');
3932
- }
3933
-
3934
- function find(elements, expression, index) {
3935
- index = index || 0;
3936
- var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
3937
-
3938
- for (i = 0; i < length; i++) {
3939
- if (match(elements[i], expression) && index == matchIndex++) {
3940
- return Element.extend(elements[i]);
3941
- }
3942
- }
3943
- }
3944
-
3945
- function extendElements(elements) {
3946
- for (var i = 0, length = elements.length; i < length; i++) {
3947
- Element.extend(elements[i]);
3948
- }
3949
- return elements;
3950
- }
3951
-
3952
-
3953
- var K = Prototype.K;
3954
-
3955
- return {
3956
- select: select,
3957
- match: match,
3958
- find: find,
3959
- extendElements: (Element.extend === K) ? K : extendElements,
3960
- extendElement: Element.extend
3961
- };
3962
- })();
3963
- /*!
3964
- * Sizzle CSS Selector Engine - v1.0
3965
- * Copyright 2009, The Dojo Foundation
3966
- * Released under the MIT, BSD, and GPL Licenses.
3967
- * More information: http://sizzlejs.com/
3968
- */
3969
- (function(){
3970
-
3971
- var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3972
- done = 0,
3973
- toString = Object.prototype.toString,
3974
- hasDuplicate = false,
3975
- baseHasDuplicate = true;
3976
-
3977
- [0, 0].sort(function(){
3978
- baseHasDuplicate = false;
3979
- return 0;
3980
- });
3981
-
3982
- var Sizzle = function(selector, context, results, seed) {
3983
- results = results || [];
3984
- var origContext = context = context || document;
3985
-
3986
- if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3987
- return [];
3988
- }
3989
-
3990
- if ( !selector || typeof selector !== "string" ) {
3991
- return results;
3992
- }
3993
-
3994
- var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
3995
- soFar = selector;
3996
-
3997
- while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
3998
- soFar = m[3];
3999
-
4000
- parts.push( m[1] );
4001
-
4002
- if ( m[2] ) {
4003
- extra = m[3];
4004
- break;
4005
- }
4006
- }
4007
-
4008
- if ( parts.length > 1 && origPOS.exec( selector ) ) {
4009
- if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4010
- set = posProcess( parts[0] + parts[1], context );
4011
- } else {
4012
- set = Expr.relative[ parts[0] ] ?
4013
- [ context ] :
4014
- Sizzle( parts.shift(), context );
4015
-
4016
- while ( parts.length ) {
4017
- selector = parts.shift();
4018
-
4019
- if ( Expr.relative[ selector ] )
4020
- selector += parts.shift();
4021
-
4022
- set = posProcess( selector, set );
4023
- }
4024
- }
4025
- } else {
4026
- if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4027
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4028
- var ret = Sizzle.find( parts.shift(), context, contextXML );
4029
- context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
4030
- }
4031
-
4032
- if ( context ) {
4033
- var ret = seed ?
4034
- { expr: parts.pop(), set: makeArray(seed) } :
4035
- Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4036
- set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
4037
-
4038
- if ( parts.length > 0 ) {
4039
- checkSet = makeArray(set);
4040
- } else {
4041
- prune = false;
4042
- }
4043
-
4044
- while ( parts.length ) {
4045
- var cur = parts.pop(), pop = cur;
4046
-
4047
- if ( !Expr.relative[ cur ] ) {
4048
- cur = "";
4049
- } else {
4050
- pop = parts.pop();
4051
- }
4052
-
4053
- if ( pop == null ) {
4054
- pop = context;
4055
- }
4056
-
4057
- Expr.relative[ cur ]( checkSet, pop, contextXML );
4058
- }
4059
- } else {
4060
- checkSet = parts = [];
4061
- }
4062
- }
4063
-
4064
- if ( !checkSet ) {
4065
- checkSet = set;
4066
- }
4067
-
4068
- if ( !checkSet ) {
4069
- throw "Syntax error, unrecognized expression: " + (cur || selector);
4070
- }
4071
-
4072
- if ( toString.call(checkSet) === "[object Array]" ) {
4073
- if ( !prune ) {
4074
- results.push.apply( results, checkSet );
4075
- } else if ( context && context.nodeType === 1 ) {
4076
- for ( var i = 0; checkSet[i] != null; i++ ) {
4077
- if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
4078
- results.push( set[i] );
4079
- }
4080
- }
4081
- } else {
4082
- for ( var i = 0; checkSet[i] != null; i++ ) {
4083
- if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4084
- results.push( set[i] );
4085
- }
4086
- }
4087
- }
4088
- } else {
4089
- makeArray( checkSet, results );
4090
- }
4091
-
4092
- if ( extra ) {
4093
- Sizzle( extra, origContext, results, seed );
4094
- Sizzle.uniqueSort( results );
4095
- }
4096
-
4097
- return results;
4098
- };
4099
-
4100
- Sizzle.uniqueSort = function(results){
4101
- if ( sortOrder ) {
4102
- hasDuplicate = baseHasDuplicate;
4103
- results.sort(sortOrder);
4104
-
4105
- if ( hasDuplicate ) {
4106
- for ( var i = 1; i < results.length; i++ ) {
4107
- if ( results[i] === results[i-1] ) {
4108
- results.splice(i--, 1);
4109
- }
4110
- }
4111
- }
4112
- }
4113
-
4114
- return results;
4115
- };
4116
-
4117
- Sizzle.matches = function(expr, set){
4118
- return Sizzle(expr, null, null, set);
4119
- };
4120
-
4121
- Sizzle.find = function(expr, context, isXML){
4122
- var set, match;
4123
-
4124
- if ( !expr ) {
4125
- return [];
4126
- }
4127
-
4128
- for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4129
- var type = Expr.order[i], match;
4130
-
4131
- if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4132
- var left = match[1];
4133
- match.splice(1,1);
4134
-
4135
- if ( left.substr( left.length - 1 ) !== "\\" ) {
4136
- match[1] = (match[1] || "").replace(/\\/g, "");
4137
- set = Expr.find[ type ]( match, context, isXML );
4138
- if ( set != null ) {
4139
- expr = expr.replace( Expr.match[ type ], "" );
4140
- break;
4141
- }
4142
- }
4143
- }
4144
- }
4145
-
4146
- if ( !set ) {
4147
- set = context.getElementsByTagName("*");
4148
- }
4149
-
4150
- return {set: set, expr: expr};
4151
- };
4152
-
4153
- Sizzle.filter = function(expr, set, inplace, not){
4154
- var old = expr, result = [], curLoop = set, match, anyFound,
4155
- isXMLFilter = set && set[0] && isXML(set[0]);
4156
-
4157
- while ( expr && set.length ) {
4158
- for ( var type in Expr.filter ) {
4159
- if ( (match = Expr.match[ type ].exec( expr )) != null ) {
4160
- var filter = Expr.filter[ type ], found, item;
4161
- anyFound = false;
4162
-
4163
- if ( curLoop == result ) {
4164
- result = [];
4165
- }
4166
-
4167
- if ( Expr.preFilter[ type ] ) {
4168
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4169
-
4170
- if ( !match ) {
4171
- anyFound = found = true;
4172
- } else if ( match === true ) {
4173
- continue;
4174
- }
4175
- }
4176
-
4177
- if ( match ) {
4178
- for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4179
- if ( item ) {
4180
- found = filter( item, match, i, curLoop );
4181
- var pass = not ^ !!found;
4182
-
4183
- if ( inplace && found != null ) {
4184
- if ( pass ) {
4185
- anyFound = true;
4186
- } else {
4187
- curLoop[i] = false;
4188
- }
4189
- } else if ( pass ) {
4190
- result.push( item );
4191
- anyFound = true;
4192
- }
4193
- }
4194
- }
4195
- }
4196
-
4197
- if ( found !== undefined ) {
4198
- if ( !inplace ) {
4199
- curLoop = result;
4200
- }
4201
-
4202
- expr = expr.replace( Expr.match[ type ], "" );
4203
-
4204
- if ( !anyFound ) {
4205
- return [];
4206
- }
4207
-
4208
- break;
4209
- }
4210
- }
4211
- }
4212
-
4213
- if ( expr == old ) {
4214
- if ( anyFound == null ) {
4215
- throw "Syntax error, unrecognized expression: " + expr;
4216
- } else {
4217
- break;
4218
- }
4219
- }
4220
-
4221
- old = expr;
4222
- }
4223
-
4224
- return curLoop;
4225
- };
4226
-
4227
- var Expr = Sizzle.selectors = {
4228
- order: [ "ID", "NAME", "TAG" ],
4229
- match: {
4230
- ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4231
- CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4232
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
4233
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
4234
- TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
4235
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
4236
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
4237
- PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
4238
- },
4239
- leftMatch: {},
4240
- attrMap: {
4241
- "class": "className",
4242
- "for": "htmlFor"
4243
- },
4244
- attrHandle: {
4245
- href: function(elem){
4246
- return elem.getAttribute("href");
4247
- }
4248
- },
4249
- relative: {
4250
- "+": function(checkSet, part, isXML){
4251
- var isPartStr = typeof part === "string",
4252
- isTag = isPartStr && !/\W/.test(part),
4253
- isPartStrNotTag = isPartStr && !isTag;
4254
-
4255
- if ( isTag && !isXML ) {
4256
- part = part.toUpperCase();
4257
- }
4258
-
4259
- for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4260
- if ( (elem = checkSet[i]) ) {
4261
- while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4262
-
4263
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
4264
- elem || false :
4265
- elem === part;
4266
- }
4267
- }
4268
-
4269
- if ( isPartStrNotTag ) {
4270
- Sizzle.filter( part, checkSet, true );
4271
- }
4272
- },
4273
- ">": function(checkSet, part, isXML){
4274
- var isPartStr = typeof part === "string";
4275
-
4276
- if ( isPartStr && !/\W/.test(part) ) {
4277
- part = isXML ? part : part.toUpperCase();
4278
-
4279
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4280
- var elem = checkSet[i];
4281
- if ( elem ) {
4282
- var parent = elem.parentNode;
4283
- checkSet[i] = parent.nodeName === part ? parent : false;
4284
- }
4285
- }
4286
- } else {
4287
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4288
- var elem = checkSet[i];
4289
- if ( elem ) {
4290
- checkSet[i] = isPartStr ?
4291
- elem.parentNode :
4292
- elem.parentNode === part;
4293
- }
4294
- }
4295
-
4296
- if ( isPartStr ) {
4297
- Sizzle.filter( part, checkSet, true );
4298
- }
4299
- }
4300
- },
4301
- "": function(checkSet, part, isXML){
4302
- var doneName = done++, checkFn = dirCheck;
4303
-
4304
- if ( !/\W/.test(part) ) {
4305
- var nodeCheck = part = isXML ? part : part.toUpperCase();
4306
- checkFn = dirNodeCheck;
4307
- }
4308
-
4309
- checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
4310
- },
4311
- "~": function(checkSet, part, isXML){
4312
- var doneName = done++, checkFn = dirCheck;
4313
-
4314
- if ( typeof part === "string" && !/\W/.test(part) ) {
4315
- var nodeCheck = part = isXML ? part : part.toUpperCase();
4316
- checkFn = dirNodeCheck;
4317
- }
4318
-
4319
- checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
4320
- }
4321
- },
4322
- find: {
4323
- ID: function(match, context, isXML){
4324
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
4325
- var m = context.getElementById(match[1]);
4326
- return m ? [m] : [];
4327
- }
4328
- },
4329
- NAME: function(match, context, isXML){
4330
- if ( typeof context.getElementsByName !== "undefined" ) {
4331
- var ret = [], results = context.getElementsByName(match[1]);
4332
-
4333
- for ( var i = 0, l = results.length; i < l; i++ ) {
4334
- if ( results[i].getAttribute("name") === match[1] ) {
4335
- ret.push( results[i] );
4336
- }
4337
- }
4338
-
4339
- return ret.length === 0 ? null : ret;
4340
- }
4341
- },
4342
- TAG: function(match, context){
4343
- return context.getElementsByTagName(match[1]);
4344
- }
4345
- },
4346
- preFilter: {
4347
- CLASS: function(match, curLoop, inplace, result, not, isXML){
4348
- match = " " + match[1].replace(/\\/g, "") + " ";
4349
-
4350
- if ( isXML ) {
4351
- return match;
4352
- }
4353
-
4354
- for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4355
- if ( elem ) {
4356
- if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
4357
- if ( !inplace )
4358
- result.push( elem );
4359
- } else if ( inplace ) {
4360
- curLoop[i] = false;
4361
- }
4362
- }
4363
- }
4364
-
4365
- return false;
4366
- },
4367
- ID: function(match){
4368
- return match[1].replace(/\\/g, "");
4369
- },
4370
- TAG: function(match, curLoop){
4371
- for ( var i = 0; curLoop[i] === false; i++ ){}
4372
- return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
4373
- },
4374
- CHILD: function(match){
4375
- if ( match[1] == "nth" ) {
4376
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
4377
- match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
4378
- !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4379
-
4380
- match[2] = (test[1] + (test[2] || 1)) - 0;
4381
- match[3] = test[3] - 0;
4382
- }
4383
-
4384
- match[0] = done++;
4385
-
4386
- return match;
4387
- },
4388
- ATTR: function(match, curLoop, inplace, result, not, isXML){
4389
- var name = match[1].replace(/\\/g, "");
4390
-
4391
- if ( !isXML && Expr.attrMap[name] ) {
4392
- match[1] = Expr.attrMap[name];
4393
- }
4394
-
4395
- if ( match[2] === "~=" ) {
4396
- match[4] = " " + match[4] + " ";
4397
- }
4398
-
4399
- return match;
4400
- },
4401
- PSEUDO: function(match, curLoop, inplace, result, not){
4402
- if ( match[1] === "not" ) {
4403
- if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4404
- match[3] = Sizzle(match[3], null, null, curLoop);
4405
- } else {
4406
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4407
- if ( !inplace ) {
4408
- result.push.apply( result, ret );
4409
- }
4410
- return false;
4411
- }
4412
- } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4413
- return true;
4414
- }
4415
-
4416
- return match;
4417
- },
4418
- POS: function(match){
4419
- match.unshift( true );
4420
- return match;
4421
- }
4422
- },
4423
- filters: {
4424
- enabled: function(elem){
4425
- return elem.disabled === false && elem.type !== "hidden";
4426
- },
4427
- disabled: function(elem){
4428
- return elem.disabled === true;
4429
- },
4430
- checked: function(elem){
4431
- return elem.checked === true;
4432
- },
4433
- selected: function(elem){
4434
- elem.parentNode.selectedIndex;
4435
- return elem.selected === true;
4436
- },
4437
- parent: function(elem){
4438
- return !!elem.firstChild;
4439
- },
4440
- empty: function(elem){
4441
- return !elem.firstChild;
4442
- },
4443
- has: function(elem, i, match){
4444
- return !!Sizzle( match[3], elem ).length;
4445
- },
4446
- header: function(elem){
4447
- return /h\d/i.test( elem.nodeName );
4448
- },
4449
- text: function(elem){
4450
- return "text" === elem.type;
4451
- },
4452
- radio: function(elem){
4453
- return "radio" === elem.type;
4454
- },
4455
- checkbox: function(elem){
4456
- return "checkbox" === elem.type;
4457
- },
4458
- file: function(elem){
4459
- return "file" === elem.type;
4460
- },
4461
- password: function(elem){
4462
- return "password" === elem.type;
4463
- },
4464
- submit: function(elem){
4465
- return "submit" === elem.type;
4466
- },
4467
- image: function(elem){
4468
- return "image" === elem.type;
4469
- },
4470
- reset: function(elem){
4471
- return "reset" === elem.type;
4472
- },
4473
- button: function(elem){
4474
- return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
4475
- },
4476
- input: function(elem){
4477
- return /input|select|textarea|button/i.test(elem.nodeName);
4478
- }
4479
- },
4480
- setFilters: {
4481
- first: function(elem, i){
4482
- return i === 0;
4483
- },
4484
- last: function(elem, i, match, array){
4485
- return i === array.length - 1;
4486
- },
4487
- even: function(elem, i){
4488
- return i % 2 === 0;
4489
- },
4490
- odd: function(elem, i){
4491
- return i % 2 === 1;
4492
- },
4493
- lt: function(elem, i, match){
4494
- return i < match[3] - 0;
4495
- },
4496
- gt: function(elem, i, match){
4497
- return i > match[3] - 0;
4498
- },
4499
- nth: function(elem, i, match){
4500
- return match[3] - 0 == i;
4501
- },
4502
- eq: function(elem, i, match){
4503
- return match[3] - 0 == i;
4504
- }
4505
- },
4506
- filter: {
4507
- PSEUDO: function(elem, match, i, array){
4508
- var name = match[1], filter = Expr.filters[ name ];
4509
-
4510
- if ( filter ) {
4511
- return filter( elem, i, match, array );
4512
- } else if ( name === "contains" ) {
4513
- return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
4514
- } else if ( name === "not" ) {
4515
- var not = match[3];
4516
-
4517
- for ( var i = 0, l = not.length; i < l; i++ ) {
4518
- if ( not[i] === elem ) {
4519
- return false;
4520
- }
4521
- }
4522
-
4523
- return true;
4524
- }
4525
- },
4526
- CHILD: function(elem, match){
4527
- var type = match[1], node = elem;
4528
- switch (type) {
4529
- case 'only':
4530
- case 'first':
4531
- while ( (node = node.previousSibling) ) {
4532
- if ( node.nodeType === 1 ) return false;
4533
- }
4534
- if ( type == 'first') return true;
4535
- node = elem;
4536
- case 'last':
4537
- while ( (node = node.nextSibling) ) {
4538
- if ( node.nodeType === 1 ) return false;
4539
- }
4540
- return true;
4541
- case 'nth':
4542
- var first = match[2], last = match[3];
4543
-
4544
- if ( first == 1 && last == 0 ) {
4545
- return true;
4546
- }
4547
-
4548
- var doneName = match[0],
4549
- parent = elem.parentNode;
4550
-
4551
- if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4552
- var count = 0;
4553
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
4554
- if ( node.nodeType === 1 ) {
4555
- node.nodeIndex = ++count;
4556
- }
4557
- }
4558
- parent.sizcache = doneName;
4559
- }
4560
-
4561
- var diff = elem.nodeIndex - last;
4562
- if ( first == 0 ) {
4563
- return diff == 0;
4564
- } else {
4565
- return ( diff % first == 0 && diff / first >= 0 );
4566
- }
4567
- }
4568
- },
4569
- ID: function(elem, match){
4570
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
4571
- },
4572
- TAG: function(elem, match){
4573
- return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
4574
- },
4575
- CLASS: function(elem, match){
4576
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
4577
- .indexOf( match ) > -1;
4578
- },
4579
- ATTR: function(elem, match){
4580
- var name = match[1],
4581
- result = Expr.attrHandle[ name ] ?
4582
- Expr.attrHandle[ name ]( elem ) :
4583
- elem[ name ] != null ?
4584
- elem[ name ] :
4585
- elem.getAttribute( name ),
4586
- value = result + "",
4587
- type = match[2],
4588
- check = match[4];
4589
-
4590
- return result == null ?
4591
- type === "!=" :
4592
- type === "=" ?
4593
- value === check :
4594
- type === "*=" ?
4595
- value.indexOf(check) >= 0 :
4596
- type === "~=" ?
4597
- (" " + value + " ").indexOf(check) >= 0 :
4598
- !check ?
4599
- value && result !== false :
4600
- type === "!=" ?
4601
- value != check :
4602
- type === "^=" ?
4603
- value.indexOf(check) === 0 :
4604
- type === "$=" ?
4605
- value.substr(value.length - check.length) === check :
4606
- type === "|=" ?
4607
- value === check || value.substr(0, check.length + 1) === check + "-" :
4608
- false;
4609
- },
4610
- POS: function(elem, match, i, array){
4611
- var name = match[2], filter = Expr.setFilters[ name ];
4612
-
4613
- if ( filter ) {
4614
- return filter( elem, i, match, array );
4615
- }
4616
- }
4617
- }
4618
- };
4619
-
4620
- var origPOS = Expr.match.POS;
4621
-
4622
- for ( var type in Expr.match ) {
4623
- Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
4624
- Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
4625
- }
4626
-
4627
- var makeArray = function(array, results) {
4628
- array = Array.prototype.slice.call( array, 0 );
4629
-
4630
- if ( results ) {
4631
- results.push.apply( results, array );
4632
- return results;
4633
- }
4634
-
4635
- return array;
4636
- };
4637
-
4638
- try {
4639
- Array.prototype.slice.call( document.documentElement.childNodes, 0 );
4640
-
4641
- } catch(e){
4642
- makeArray = function(array, results) {
4643
- var ret = results || [];
4644
-
4645
- if ( toString.call(array) === "[object Array]" ) {
4646
- Array.prototype.push.apply( ret, array );
4647
- } else {
4648
- if ( typeof array.length === "number" ) {
4649
- for ( var i = 0, l = array.length; i < l; i++ ) {
4650
- ret.push( array[i] );
4651
- }
4652
- } else {
4653
- for ( var i = 0; array[i]; i++ ) {
4654
- ret.push( array[i] );
4655
- }
4656
- }
4657
- }
4658
-
4659
- return ret;
4660
- };
4661
- }
4662
-
4663
- var sortOrder;
4664
-
4665
- if ( document.documentElement.compareDocumentPosition ) {
4666
- sortOrder = function( a, b ) {
4667
- if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4668
- if ( a == b ) {
4669
- hasDuplicate = true;
4670
- }
4671
- return 0;
4672
- }
4673
-
4674
- var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
4675
- if ( ret === 0 ) {
4676
- hasDuplicate = true;
4677
- }
4678
- return ret;
4679
- };
4680
- } else if ( "sourceIndex" in document.documentElement ) {
4681
- sortOrder = function( a, b ) {
4682
- if ( !a.sourceIndex || !b.sourceIndex ) {
4683
- if ( a == b ) {
4684
- hasDuplicate = true;
4685
- }
4686
- return 0;
4687
- }
4688
-
4689
- var ret = a.sourceIndex - b.sourceIndex;
4690
- if ( ret === 0 ) {
4691
- hasDuplicate = true;
4692
- }
4693
- return ret;
4694
- };
4695
- } else if ( document.createRange ) {
4696
- sortOrder = function( a, b ) {
4697
- if ( !a.ownerDocument || !b.ownerDocument ) {
4698
- if ( a == b ) {
4699
- hasDuplicate = true;
4700
- }
4701
- return 0;
4702
- }
4703
-
4704
- var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
4705
- aRange.setStart(a, 0);
4706
- aRange.setEnd(a, 0);
4707
- bRange.setStart(b, 0);
4708
- bRange.setEnd(b, 0);
4709
- var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
4710
- if ( ret === 0 ) {
4711
- hasDuplicate = true;
4712
- }
4713
- return ret;
4714
- };
4715
- }
4716
-
4717
- (function(){
4718
- var form = document.createElement("div"),
4719
- id = "script" + (new Date).getTime();
4720
- form.innerHTML = "<a name='" + id + "'/>";
4721
-
4722
- var root = document.documentElement;
4723
- root.insertBefore( form, root.firstChild );
4724
-
4725
- if ( !!document.getElementById( id ) ) {
4726
- Expr.find.ID = function(match, context, isXML){
4727
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
4728
- var m = context.getElementById(match[1]);
4729
- return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
4730
- }
4731
- };
4732
-
4733
- Expr.filter.ID = function(elem, match){
4734
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4735
- return elem.nodeType === 1 && node && node.nodeValue === match;
4736
- };
4737
- }
4738
-
4739
- root.removeChild( form );
4740
- root = form = null; // release memory in IE
4741
- })();
4742
-
4743
- (function(){
4744
-
4745
- var div = document.createElement("div");
4746
- div.appendChild( document.createComment("") );
4747
-
4748
- if ( div.getElementsByTagName("*").length > 0 ) {
4749
- Expr.find.TAG = function(match, context){
4750
- var results = context.getElementsByTagName(match[1]);
4751
-
4752
- if ( match[1] === "*" ) {
4753
- var tmp = [];
4754
-
4755
- for ( var i = 0; results[i]; i++ ) {
4756
- if ( results[i].nodeType === 1 ) {
4757
- tmp.push( results[i] );
4758
- }
4759
- }
4760
-
4761
- results = tmp;
4762
- }
4763
-
4764
- return results;
4765
- };
4766
- }
4767
-
4768
- div.innerHTML = "<a href='#'></a>";
4769
- if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4770
- div.firstChild.getAttribute("href") !== "#" ) {
4771
- Expr.attrHandle.href = function(elem){
4772
- return elem.getAttribute("href", 2);
4773
- };
4774
- }
4775
-
4776
- div = null; // release memory in IE
4777
- })();
4778
-
4779
- if ( document.querySelectorAll ) (function(){
4780
- var oldSizzle = Sizzle, div = document.createElement("div");
4781
- div.innerHTML = "<p class='TEST'></p>";
4782
-
4783
- if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4784
- return;
4785
- }
4786
-
4787
- Sizzle = function(query, context, extra, seed){
4788
- context = context || document;
4789
-
4790
- if ( !seed && context.nodeType === 9 && !isXML(context) ) {
4791
- try {
4792
- return makeArray( context.querySelectorAll(query), extra );
4793
- } catch(e){}
4794
- }
4795
-
4796
- return oldSizzle(query, context, extra, seed);
4797
- };
4798
-
4799
- for ( var prop in oldSizzle ) {
4800
- Sizzle[ prop ] = oldSizzle[ prop ];
4801
- }
4802
-
4803
- div = null; // release memory in IE
4804
- })();
4805
-
4806
- if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
4807
- var div = document.createElement("div");
4808
- div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4809
-
4810
- if ( div.getElementsByClassName("e").length === 0 )
4811
- return;
4812
-
4813
- div.lastChild.className = "e";
4814
-
4815
- if ( div.getElementsByClassName("e").length === 1 )
4816
- return;
4817
-
4818
- Expr.order.splice(1, 0, "CLASS");
4819
- Expr.find.CLASS = function(match, context, isXML) {
4820
- if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4821
- return context.getElementsByClassName(match[1]);
4822
- }
4823
- };
4824
-
4825
- div = null; // release memory in IE
4826
- })();
4827
-
4828
- function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4829
- var sibDir = dir == "previousSibling" && !isXML;
4830
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4831
- var elem = checkSet[i];
4832
- if ( elem ) {
4833
- if ( sibDir && elem.nodeType === 1 ){
4834
- elem.sizcache = doneName;
4835
- elem.sizset = i;
4836
- }
4837
- elem = elem[dir];
4838
- var match = false;
4839
-
4840
- while ( elem ) {
4841
- if ( elem.sizcache === doneName ) {
4842
- match = checkSet[elem.sizset];
4843
- break;
4844
- }
4845
-
4846
- if ( elem.nodeType === 1 && !isXML ){
4847
- elem.sizcache = doneName;
4848
- elem.sizset = i;
4849
- }
4850
-
4851
- if ( elem.nodeName === cur ) {
4852
- match = elem;
4853
- break;
4854
- }
4855
-
4856
- elem = elem[dir];
4857
- }
4858
-
4859
- checkSet[i] = match;
4860
- }
4861
- }
4862
- }
4863
-
4864
- function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4865
- var sibDir = dir == "previousSibling" && !isXML;
4866
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4867
- var elem = checkSet[i];
4868
- if ( elem ) {
4869
- if ( sibDir && elem.nodeType === 1 ) {
4870
- elem.sizcache = doneName;
4871
- elem.sizset = i;
4872
- }
4873
- elem = elem[dir];
4874
- var match = false;
4875
-
4876
- while ( elem ) {
4877
- if ( elem.sizcache === doneName ) {
4878
- match = checkSet[elem.sizset];
4879
- break;
4880
- }
4881
-
4882
- if ( elem.nodeType === 1 ) {
4883
- if ( !isXML ) {
4884
- elem.sizcache = doneName;
4885
- elem.sizset = i;
4886
- }
4887
- if ( typeof cur !== "string" ) {
4888
- if ( elem === cur ) {
4889
- match = true;
4890
- break;
4891
- }
4892
-
4893
- } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4894
- match = elem;
4895
- break;
4896
- }
4897
- }
4898
-
4899
- elem = elem[dir];
4900
- }
4901
-
4902
- checkSet[i] = match;
4903
- }
4904
- }
4905
- }
4906
-
4907
- var contains = document.compareDocumentPosition ? function(a, b){
4908
- return a.compareDocumentPosition(b) & 16;
4909
- } : function(a, b){
4910
- return a !== b && (a.contains ? a.contains(b) : true);
4911
- };
4912
-
4913
- var isXML = function(elem){
4914
- return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
4915
- !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
4916
- };
4917
-
4918
- var posProcess = function(selector, context){
4919
- var tmpSet = [], later = "", match,
4920
- root = context.nodeType ? [context] : context;
4921
-
4922
- while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4923
- later += match[0];
4924
- selector = selector.replace( Expr.match.PSEUDO, "" );
4925
- }
4926
-
4927
- selector = Expr.relative[selector] ? selector + "*" : selector;
4928
-
4929
- for ( var i = 0, l = root.length; i < l; i++ ) {
4930
- Sizzle( selector, root[i], tmpSet );
4931
- }
4932
-
4933
- return Sizzle.filter( later, tmpSet );
4934
- };
4935
-
4936
-
4937
- window.Sizzle = Sizzle;
4938
-
4939
- })();
4940
-
4941
- Prototype._original_property = window.Sizzle;
4942
-
4943
- ;(function(engine) {
4944
- var extendElements = Prototype.Selector.extendElements;
4945
-
4946
- function select(selector, scope) {
4947
- return extendElements(engine(selector, scope || document));
4948
- }
4949
-
4950
- function match(element, selector) {
4951
- return engine.matches(selector, [element]).length == 1;
4952
- }
4953
-
4954
- Prototype.Selector.engine = engine;
4955
- Prototype.Selector.select = select;
4956
- Prototype.Selector.match = match;
4957
- })(Sizzle);
4958
-
4959
- window.Sizzle = Prototype._original_property;
4960
- delete Prototype._original_property;
4961
-
4962
- var Form = {
4963
- reset: function(form) {
4964
- form = $(form);
4965
- form.reset();
4966
- return form;
4967
- },
4968
-
4969
- serializeElements: function(elements, options) {
4970
- if (typeof options != 'object') options = { hash: !!options };
4971
- else if (Object.isUndefined(options.hash)) options.hash = true;
4972
- var key, value, submitted = false, submit = options.submit, accumulator, initial;
4973
-
4974
- if (options.hash) {
4975
- initial = {};
4976
- accumulator = function(result, key, value) {
4977
- if (key in result) {
4978
- if (!Object.isArray(result[key])) result[key] = [result[key]];
4979
- result[key].push(value);
4980
- } else result[key] = value;
4981
- return result;
4982
- };
4983
- } else {
4984
- initial = '';
4985
- accumulator = function(result, key, value) {
4986
- return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
4987
- }
4988
- }
4989
-
4990
- return elements.inject(initial, function(result, element) {
4991
- if (!element.disabled && element.name) {
4992
- key = element.name; value = $(element).getValue();
4993
- if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
4994
- submit !== false && (!submit || key == submit) && (submitted = true)))) {
4995
- result = accumulator(result, key, value);
4996
- }
4997
- }
4998
- return result;
4999
- });
5000
- }
5001
- };
5002
-
5003
- Form.Methods = {
5004
- serialize: function(form, options) {
5005
- return Form.serializeElements(Form.getElements(form), options);
5006
- },
5007
-
5008
- getElements: function(form) {
5009
- var elements = $(form).getElementsByTagName('*'),
5010
- element,
5011
- arr = [ ],
5012
- serializers = Form.Element.Serializers;
5013
- for (var i = 0; element = elements[i]; i++) {
5014
- arr.push(element);
5015
- }
5016
- return arr.inject([], function(elements, child) {
5017
- if (serializers[child.tagName.toLowerCase()])
5018
- elements.push(Element.extend(child));
5019
- return elements;
5020
- })
5021
- },
5022
-
5023
- getInputs: function(form, typeName, name) {
5024
- form = $(form);
5025
- var inputs = form.getElementsByTagName('input');
5026
-
5027
- if (!typeName && !name) return $A(inputs).map(Element.extend);
5028
-
5029
- for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
5030
- var input = inputs[i];
5031
- if ((typeName && input.type != typeName) || (name && input.name != name))
5032
- continue;
5033
- matchingInputs.push(Element.extend(input));
5034
- }
5035
-
5036
- return matchingInputs;
5037
- },
5038
-
5039
- disable: function(form) {
5040
- form = $(form);
5041
- Form.getElements(form).invoke('disable');
5042
- return form;
5043
- },
5044
-
5045
- enable: function(form) {
5046
- form = $(form);
5047
- Form.getElements(form).invoke('enable');
5048
- return form;
5049
- },
5050
-
5051
- findFirstElement: function(form) {
5052
- var elements = $(form).getElements().findAll(function(element) {
5053
- return 'hidden' != element.type && !element.disabled;
5054
- });
5055
- var firstByIndex = elements.findAll(function(element) {
5056
- return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
5057
- }).sortBy(function(element) { return element.tabIndex }).first();
5058
-
5059
- return firstByIndex ? firstByIndex : elements.find(function(element) {
5060
- return /^(?:input|select|textarea)$/i.test(element.tagName);
5061
- });
5062
- },
5063
-
5064
- focusFirstElement: function(form) {
5065
- form = $(form);
5066
- var element = form.findFirstElement();
5067
- if (element) element.activate();
5068
- return form;
5069
- },
5070
-
5071
- request: function(form, options) {
5072
- form = $(form), options = Object.clone(options || { });
5073
-
5074
- var params = options.parameters, action = form.readAttribute('action') || '';
5075
- if (action.blank()) action = window.location.href;
5076
- options.parameters = form.serialize(true);
5077
-
5078
- if (params) {
5079
- if (Object.isString(params)) params = params.toQueryParams();
5080
- Object.extend(options.parameters, params);
5081
- }
5082
-
5083
- if (form.hasAttribute('method') && !options.method)
5084
- options.method = form.method;
5085
-
5086
- return new Ajax.Request(action, options);
5087
- }
5088
- };
5089
-
5090
- /*--------------------------------------------------------------------------*/
5091
-
5092
-
5093
- Form.Element = {
5094
- focus: function(element) {
5095
- $(element).focus();
5096
- return element;
5097
- },
5098
-
5099
- select: function(element) {
5100
- $(element).select();
5101
- return element;
5102
- }
5103
- };
5104
-
5105
- Form.Element.Methods = {
5106
-
5107
- serialize: function(element) {
5108
- element = $(element);
5109
- if (!element.disabled && element.name) {
5110
- var value = element.getValue();
5111
- if (value != undefined) {
5112
- var pair = { };
5113
- pair[element.name] = value;
5114
- return Object.toQueryString(pair);
5115
- }
5116
- }
5117
- return '';
5118
- },
5119
-
5120
- getValue: function(element) {
5121
- element = $(element);
5122
- var method = element.tagName.toLowerCase();
5123
- return Form.Element.Serializers[method](element);
5124
- },
5125
-
5126
- setValue: function(element, value) {
5127
- element = $(element);
5128
- var method = element.tagName.toLowerCase();
5129
- Form.Element.Serializers[method](element, value);
5130
- return element;
5131
- },
5132
-
5133
- clear: function(element) {
5134
- $(element).value = '';
5135
- return element;
5136
- },
5137
-
5138
- present: function(element) {
5139
- return $(element).value != '';
5140
- },
5141
-
5142
- activate: function(element) {
5143
- element = $(element);
5144
- try {
5145
- element.focus();
5146
- if (element.select && (element.tagName.toLowerCase() != 'input' ||
5147
- !(/^(?:button|reset|submit)$/i.test(element.type))))
5148
- element.select();
5149
- } catch (e) { }
5150
- return element;
5151
- },
5152
-
5153
- disable: function(element) {
5154
- element = $(element);
5155
- element.disabled = true;
5156
- return element;
5157
- },
5158
-
5159
- enable: function(element) {
5160
- element = $(element);
5161
- element.disabled = false;
5162
- return element;
5163
- }
5164
- };
5165
-
5166
- /*--------------------------------------------------------------------------*/
5167
-
5168
- var Field = Form.Element;
5169
-
5170
- var $F = Form.Element.Methods.getValue;
5171
-
5172
- /*--------------------------------------------------------------------------*/
5173
-
5174
- Form.Element.Serializers = (function() {
5175
- function input(element, value) {
5176
- switch (element.type.toLowerCase()) {
5177
- case 'checkbox':
5178
- case 'radio':
5179
- return inputSelector(element, value);
5180
- default:
5181
- return valueSelector(element, value);
5182
- }
5183
- }
5184
-
5185
- function inputSelector(element, value) {
5186
- if (Object.isUndefined(value))
5187
- return element.checked ? element.value : null;
5188
- else element.checked = !!value;
5189
- }
5190
-
5191
- function valueSelector(element, value) {
5192
- if (Object.isUndefined(value)) return element.value;
5193
- else element.value = value;
5194
- }
5195
-
5196
- function select(element, value) {
5197
- if (Object.isUndefined(value))
5198
- return (element.type === 'select-one' ? selectOne : selectMany)(element);
5199
-
5200
- var opt, currentValue, single = !Object.isArray(value);
5201
- for (var i = 0, length = element.length; i < length; i++) {
5202
- opt = element.options[i];
5203
- currentValue = this.optionValue(opt);
5204
- if (single) {
5205
- if (currentValue == value) {
5206
- opt.selected = true;
5207
- return;
5208
- }
5209
- }
5210
- else opt.selected = value.include(currentValue);
5211
- }
5212
- }
5213
-
5214
- function selectOne(element) {
5215
- var index = element.selectedIndex;
5216
- return index >= 0 ? optionValue(element.options[index]) : null;
5217
- }
5218
-
5219
- function selectMany(element) {
5220
- var values, length = element.length;
5221
- if (!length) return null;
5222
-
5223
- for (var i = 0, values = []; i < length; i++) {
5224
- var opt = element.options[i];
5225
- if (opt.selected) values.push(optionValue(opt));
5226
- }
5227
- return values;
5228
- }
5229
-
5230
- function optionValue(opt) {
5231
- return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
5232
- }
5233
-
5234
- return {
5235
- input: input,
5236
- inputSelector: inputSelector,
5237
- textarea: valueSelector,
5238
- select: select,
5239
- selectOne: selectOne,
5240
- selectMany: selectMany,
5241
- optionValue: optionValue,
5242
- button: valueSelector
5243
- };
5244
- })();
5245
-
5246
- /*--------------------------------------------------------------------------*/
5247
-
5248
-
5249
- Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
5250
- initialize: function($super, element, frequency, callback) {
5251
- $super(callback, frequency);
5252
- this.element = $(element);
5253
- this.lastValue = this.getValue();
5254
- },
5255
-
5256
- execute: function() {
5257
- var value = this.getValue();
5258
- if (Object.isString(this.lastValue) && Object.isString(value) ?
5259
- this.lastValue != value : String(this.lastValue) != String(value)) {
5260
- this.callback(this.element, value);
5261
- this.lastValue = value;
5262
- }
5263
- }
5264
- });
5265
-
5266
- Form.Element.Observer = Class.create(Abstract.TimedObserver, {
5267
- getValue: function() {
5268
- return Form.Element.getValue(this.element);
5269
- }
5270
- });
5271
-
5272
- Form.Observer = Class.create(Abstract.TimedObserver, {
5273
- getValue: function() {
5274
- return Form.serialize(this.element);
5275
- }
5276
- });
5277
-
5278
- /*--------------------------------------------------------------------------*/
5279
-
5280
- Abstract.EventObserver = Class.create({
5281
- initialize: function(element, callback) {
5282
- this.element = $(element);
5283
- this.callback = callback;
5284
-
5285
- this.lastValue = this.getValue();
5286
- if (this.element.tagName.toLowerCase() == 'form')
5287
- this.registerFormCallbacks();
5288
- else
5289
- this.registerCallback(this.element);
5290
- },
5291
-
5292
- onElementEvent: function() {
5293
- var value = this.getValue();
5294
- if (this.lastValue != value) {
5295
- this.callback(this.element, value);
5296
- this.lastValue = value;
5297
- }
5298
- },
5299
-
5300
- registerFormCallbacks: function() {
5301
- Form.getElements(this.element).each(this.registerCallback, this);
5302
- },
5303
-
5304
- registerCallback: function(element) {
5305
- if (element.type) {
5306
- switch (element.type.toLowerCase()) {
5307
- case 'checkbox':
5308
- case 'radio':
5309
- Event.observe(element, 'click', this.onElementEvent.bind(this));
5310
- break;
5311
- default:
5312
- Event.observe(element, 'change', this.onElementEvent.bind(this));
5313
- break;
5314
- }
5315
- }
5316
- }
5317
- });
5318
-
5319
- Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
5320
- getValue: function() {
5321
- return Form.Element.getValue(this.element);
5322
- }
5323
- });
5324
-
5325
- Form.EventObserver = Class.create(Abstract.EventObserver, {
5326
- getValue: function() {
5327
- return Form.serialize(this.element);
5328
- }
5329
- });
5330
- (function() {
5331
-
5332
- var Event = {
5333
- KEY_BACKSPACE: 8,
5334
- KEY_TAB: 9,
5335
- KEY_RETURN: 13,
5336
- KEY_ESC: 27,
5337
- KEY_LEFT: 37,
5338
- KEY_UP: 38,
5339
- KEY_RIGHT: 39,
5340
- KEY_DOWN: 40,
5341
- KEY_DELETE: 46,
5342
- KEY_HOME: 36,
5343
- KEY_END: 35,
5344
- KEY_PAGEUP: 33,
5345
- KEY_PAGEDOWN: 34,
5346
- KEY_INSERT: 45,
5347
-
5348
- cache: {}
5349
- };
5350
-
5351
- var docEl = document.documentElement;
5352
- var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
5353
- && 'onmouseleave' in docEl;
5354
-
5355
-
5356
-
5357
- var isIELegacyEvent = function(event) { return false; };
5358
-
5359
- if (window.attachEvent) {
5360
- if (window.addEventListener) {
5361
- isIELegacyEvent = function(event) {
5362
- return !(event instanceof window.Event);
5363
- };
5364
- } else {
5365
- isIELegacyEvent = function(event) { return true; };
5366
- }
5367
- }
5368
-
5369
- var _isButton;
5370
-
5371
- function _isButtonForDOMEvents(event, code) {
5372
- return event.which ? (event.which === code + 1) : (event.button === code);
5373
- }
5374
-
5375
- var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
5376
- function _isButtonForLegacyEvents(event, code) {
5377
- return event.button === legacyButtonMap[code];
5378
- }
5379
-
5380
- function _isButtonForWebKit(event, code) {
5381
- switch (code) {
5382
- case 0: return event.which == 1 && !event.metaKey;
5383
- case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
5384
- case 2: return event.which == 3;
5385
- default: return false;
5386
- }
5387
- }
5388
-
5389
- if (window.attachEvent) {
5390
- if (!window.addEventListener) {
5391
- _isButton = _isButtonForLegacyEvents;
5392
- } else {
5393
- _isButton = function(event, code) {
5394
- return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
5395
- _isButtonForDOMEvents(event, code);
5396
- }
5397
- }
5398
- } else if (Prototype.Browser.WebKit) {
5399
- _isButton = _isButtonForWebKit;
5400
- } else {
5401
- _isButton = _isButtonForDOMEvents;
5402
- }
5403
-
5404
- function isLeftClick(event) { return _isButton(event, 0) }
5405
-
5406
- function isMiddleClick(event) { return _isButton(event, 1) }
5407
-
5408
- function isRightClick(event) { return _isButton(event, 2) }
5409
-
5410
- function element(event) {
5411
- event = Event.extend(event);
5412
-
5413
- var node = event.target, type = event.type,
5414
- currentTarget = event.currentTarget;
5415
-
5416
- if (currentTarget && currentTarget.tagName) {
5417
- if (type === 'load' || type === 'error' ||
5418
- (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
5419
- && currentTarget.type === 'radio'))
5420
- node = currentTarget;
5421
- }
5422
-
5423
- if (node.nodeType == Node.TEXT_NODE)
5424
- node = node.parentNode;
5425
-
5426
- return Element.extend(node);
5427
- }
5428
-
5429
- function findElement(event, expression) {
5430
- var element = Event.element(event);
5431
-
5432
- if (!expression) return element;
5433
- while (element) {
5434
- if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
5435
- return Element.extend(element);
5436
- }
5437
- element = element.parentNode;
5438
- }
5439
- }
5440
-
5441
- function pointer(event) {
5442
- return { x: pointerX(event), y: pointerY(event) };
5443
- }
5444
-
5445
- function pointerX(event) {
5446
- var docElement = document.documentElement,
5447
- body = document.body || { scrollLeft: 0 };
5448
-
5449
- return event.pageX || (event.clientX +
5450
- (docElement.scrollLeft || body.scrollLeft) -
5451
- (docElement.clientLeft || 0));
5452
- }
5453
-
5454
- function pointerY(event) {
5455
- var docElement = document.documentElement,
5456
- body = document.body || { scrollTop: 0 };
5457
-
5458
- return event.pageY || (event.clientY +
5459
- (docElement.scrollTop || body.scrollTop) -
5460
- (docElement.clientTop || 0));
5461
- }
5462
-
5463
-
5464
- function stop(event) {
5465
- Event.extend(event);
5466
- event.preventDefault();
5467
- event.stopPropagation();
5468
-
5469
- event.stopped = true;
5470
- }
5471
-
5472
-
5473
- Event.Methods = {
5474
- isLeftClick: isLeftClick,
5475
- isMiddleClick: isMiddleClick,
5476
- isRightClick: isRightClick,
5477
-
5478
- element: element,
5479
- findElement: findElement,
5480
-
5481
- pointer: pointer,
5482
- pointerX: pointerX,
5483
- pointerY: pointerY,
5484
-
5485
- stop: stop
5486
- };
5487
-
5488
- var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
5489
- m[name] = Event.Methods[name].methodize();
5490
- return m;
5491
- });
5492
-
5493
- if (window.attachEvent) {
5494
- function _relatedTarget(event) {
5495
- var element;
5496
- switch (event.type) {
5497
- case 'mouseover':
5498
- case 'mouseenter':
5499
- element = event.fromElement;
5500
- break;
5501
- case 'mouseout':
5502
- case 'mouseleave':
5503
- element = event.toElement;
5504
- break;
5505
- default:
5506
- return null;
5507
- }
5508
- return Element.extend(element);
5509
- }
5510
-
5511
- var additionalMethods = {
5512
- stopPropagation: function() { this.cancelBubble = true },
5513
- preventDefault: function() { this.returnValue = false },
5514
- inspect: function() { return '[object Event]' }
5515
- };
5516
-
5517
- Event.extend = function(event, element) {
5518
- if (!event) return false;
5519
-
5520
- if (!isIELegacyEvent(event)) return event;
5521
-
5522
- if (event._extendedByPrototype) return event;
5523
- event._extendedByPrototype = Prototype.emptyFunction;
5524
-
5525
- var pointer = Event.pointer(event);
5526
-
5527
- Object.extend(event, {
5528
- target: event.srcElement || element,
5529
- relatedTarget: _relatedTarget(event),
5530
- pageX: pointer.x,
5531
- pageY: pointer.y
5532
- });
5533
-
5534
- Object.extend(event, methods);
5535
- Object.extend(event, additionalMethods);
5536
-
5537
- return event;
5538
- };
5539
- } else {
5540
- Event.extend = Prototype.K;
5541
- }
5542
-
5543
- if (window.addEventListener) {
5544
- Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
5545
- Object.extend(Event.prototype, methods);
5546
- }
5547
-
5548
- function _createResponder(element, eventName, handler) {
5549
- var registry = Element.retrieve(element, 'prototype_event_registry');
5550
-
5551
- if (Object.isUndefined(registry)) {
5552
- CACHE.push(element);
5553
- registry = Element.retrieve(element, 'prototype_event_registry', $H());
5554
- }
5555
-
5556
- var respondersForEvent = registry.get(eventName);
5557
- if (Object.isUndefined(respondersForEvent)) {
5558
- respondersForEvent = [];
5559
- registry.set(eventName, respondersForEvent);
5560
- }
5561
-
5562
- if (respondersForEvent.pluck('handler').include(handler)) return false;
5563
-
5564
- var responder;
5565
- if (eventName.include(":")) {
5566
- responder = function(event) {
5567
- if (Object.isUndefined(event.eventName))
5568
- return false;
5569
-
5570
- if (event.eventName !== eventName)
5571
- return false;
5572
-
5573
- Event.extend(event, element);
5574
- handler.call(element, event);
5575
- };
5576
- } else {
5577
- if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
5578
- (eventName === "mouseenter" || eventName === "mouseleave")) {
5579
- if (eventName === "mouseenter" || eventName === "mouseleave") {
5580
- responder = function(event) {
5581
- Event.extend(event, element);
5582
-
5583
- var parent = event.relatedTarget;
5584
- while (parent && parent !== element) {
5585
- try { parent = parent.parentNode; }
5586
- catch(e) { parent = element; }
5587
- }
5588
-
5589
- if (parent === element) return;
5590
-
5591
- handler.call(element, event);
5592
- };
5593
- }
5594
- } else {
5595
- responder = function(event) {
5596
- Event.extend(event, element);
5597
- handler.call(element, event);
5598
- };
5599
- }
5600
- }
5601
-
5602
- responder.handler = handler;
5603
- respondersForEvent.push(responder);
5604
- return responder;
5605
- }
5606
-
5607
- function _destroyCache() {
5608
- for (var i = 0, length = CACHE.length; i < length; i++) {
5609
- Event.stopObserving(CACHE[i]);
5610
- CACHE[i] = null;
5611
- }
5612
- }
5613
-
5614
- var CACHE = [];
5615
-
5616
- if (Prototype.Browser.IE)
5617
- window.attachEvent('onunload', _destroyCache);
5618
-
5619
- if (Prototype.Browser.WebKit)
5620
- window.addEventListener('unload', Prototype.emptyFunction, false);
5621
-
5622
-
5623
- var _getDOMEventName = Prototype.K,
5624
- translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
5625
-
5626
- if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
5627
- _getDOMEventName = function(eventName) {
5628
- return (translations[eventName] || eventName);
5629
- };
5630
- }
5631
-
5632
- function observe(element, eventName, handler) {
5633
- element = $(element);
5634
-
5635
- var responder = _createResponder(element, eventName, handler);
5636
-
5637
- if (!responder) return element;
5638
-
5639
- if (eventName.include(':')) {
5640
- if (element.addEventListener)
5641
- element.addEventListener("dataavailable", responder, false);
5642
- else {
5643
- element.attachEvent("ondataavailable", responder);
5644
- element.attachEvent("onlosecapture", responder);
5645
- }
5646
- } else {
5647
- var actualEventName = _getDOMEventName(eventName);
5648
-
5649
- if (element.addEventListener)
5650
- element.addEventListener(actualEventName, responder, false);
5651
- else
5652
- element.attachEvent("on" + actualEventName, responder);
5653
- }
5654
-
5655
- return element;
5656
- }
5657
-
5658
- function stopObserving(element, eventName, handler) {
5659
- element = $(element);
5660
-
5661
- var registry = Element.retrieve(element, 'prototype_event_registry');
5662
- if (!registry) return element;
5663
-
5664
- if (!eventName) {
5665
- registry.each( function(pair) {
5666
- var eventName = pair.key;
5667
- stopObserving(element, eventName);
5668
- });
5669
- return element;
5670
- }
5671
-
5672
- var responders = registry.get(eventName);
5673
- if (!responders) return element;
5674
-
5675
- if (!handler) {
5676
- responders.each(function(r) {
5677
- stopObserving(element, eventName, r.handler);
5678
- });
5679
- return element;
5680
- }
5681
-
5682
- var i = responders.length, responder;
5683
- while (i--) {
5684
- if (responders[i].handler === handler) {
5685
- responder = responders[i];
5686
- break;
5687
- }
5688
- }
5689
- if (!responder) return element;
5690
-
5691
- if (eventName.include(':')) {
5692
- if (element.removeEventListener)
5693
- element.removeEventListener("dataavailable", responder, false);
5694
- else {
5695
- element.detachEvent("ondataavailable", responder);
5696
- element.detachEvent("onlosecapture", responder);
5697
- }
5698
- } else {
5699
- var actualEventName = _getDOMEventName(eventName);
5700
- if (element.removeEventListener)
5701
- element.removeEventListener(actualEventName, responder, false);
5702
- else
5703
- element.detachEvent('on' + actualEventName, responder);
5704
- }
5705
-
5706
- registry.set(eventName, responders.without(responder));
5707
-
5708
- return element;
5709
- }
5710
-
5711
- function fire(element, eventName, memo, bubble) {
5712
- element = $(element);
5713
-
5714
- if (Object.isUndefined(bubble))
5715
- bubble = true;
5716
-
5717
- if (element == document && document.createEvent && !element.dispatchEvent)
5718
- element = document.documentElement;
5719
-
5720
- var event;
5721
- if (document.createEvent) {
5722
- event = document.createEvent('HTMLEvents');
5723
- event.initEvent('dataavailable', bubble, true);
5724
- } else {
5725
- event = document.createEventObject();
5726
- event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
5727
- }
5728
-
5729
- event.eventName = eventName;
5730
- event.memo = memo || { };
5731
-
5732
- if (document.createEvent)
5733
- element.dispatchEvent(event);
5734
- else
5735
- element.fireEvent(event.eventType, event);
5736
-
5737
- return Event.extend(event);
5738
- }
5739
-
5740
- Event.Handler = Class.create({
5741
- initialize: function(element, eventName, selector, callback) {
5742
- this.element = $(element);
5743
- this.eventName = eventName;
5744
- this.selector = selector;
5745
- this.callback = callback;
5746
- this.handler = this.handleEvent.bind(this);
5747
- },
5748
-
5749
- start: function() {
5750
- Event.observe(this.element, this.eventName, this.handler);
5751
- return this;
5752
- },
5753
-
5754
- stop: function() {
5755
- Event.stopObserving(this.element, this.eventName, this.handler);
5756
- return this;
5757
- },
5758
-
5759
- handleEvent: function(event) {
5760
- var element = Event.findElement(event, this.selector);
5761
- if (element) this.callback.call(this.element, event, element);
5762
- }
5763
- });
5764
-
5765
- function on(element, eventName, selector, callback) {
5766
- element = $(element);
5767
- if (Object.isFunction(selector) && Object.isUndefined(callback)) {
5768
- callback = selector, selector = null;
5769
- }
5770
-
5771
- return new Event.Handler(element, eventName, selector, callback).start();
5772
- }
5773
-
5774
- Object.extend(Event, Event.Methods);
5775
-
5776
- Object.extend(Event, {
5777
- fire: fire,
5778
- observe: observe,
5779
- stopObserving: stopObserving,
5780
- on: on
5781
- });
5782
-
5783
- Element.addMethods({
5784
- fire: fire,
5785
-
5786
- observe: observe,
5787
-
5788
- stopObserving: stopObserving,
5789
-
5790
- on: on
5791
- });
5792
-
5793
- Object.extend(document, {
5794
- fire: fire.methodize(),
5795
-
5796
- observe: observe.methodize(),
5797
-
5798
- stopObserving: stopObserving.methodize(),
5799
-
5800
- on: on.methodize(),
5801
-
5802
- loaded: false
5803
- });
5804
-
5805
- if (window.Event) Object.extend(window.Event, Event);
5806
- else window.Event = Event;
5807
- })();
5808
-
5809
- (function() {
5810
- /* Support for the DOMContentLoaded event is based on work by Dan Webb,
5811
- Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
5812
-
5813
- var timer;
5814
-
5815
- function fireContentLoadedEvent() {
5816
- if (document.loaded) return;
5817
- if (timer) window.clearTimeout(timer);
5818
- document.loaded = true;
5819
- document.fire('dom:loaded');
5820
- }
5821
-
5822
- function checkReadyState() {
5823
- if (document.readyState === 'complete') {
5824
- document.stopObserving('readystatechange', checkReadyState);
5825
- fireContentLoadedEvent();
5826
- }
5827
- }
5828
-
5829
- function pollDoScroll() {
5830
- try { document.documentElement.doScroll('left'); }
5831
- catch(e) {
5832
- timer = pollDoScroll.defer();
5833
- return;
5834
- }
5835
- fireContentLoadedEvent();
5836
- }
5837
-
5838
- if (document.addEventListener) {
5839
- document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
5840
- } else {
5841
- document.observe('readystatechange', checkReadyState);
5842
- if (window == top)
5843
- timer = pollDoScroll.defer();
5844
- }
5845
-
5846
- Event.observe(window, 'load', fireContentLoadedEvent);
5847
- })();
5848
-
5849
-
5850
- Element.addMethods();
5851
- /*------------------------------- DEPRECATED -------------------------------*/
5852
-
5853
- Hash.toQueryString = Object.toQueryString;
5854
-
5855
- var Toggle = { display: Element.toggle };
5856
-
5857
- Element.Methods.childOf = Element.Methods.descendantOf;
5858
-
5859
- var Insertion = {
5860
- Before: function(element, content) {
5861
- return Element.insert(element, {before:content});
5862
- },
5863
-
5864
- Top: function(element, content) {
5865
- return Element.insert(element, {top:content});
5866
- },
5867
-
5868
- Bottom: function(element, content) {
5869
- return Element.insert(element, {bottom:content});
5870
- },
5871
-
5872
- After: function(element, content) {
5873
- return Element.insert(element, {after:content});
5874
- }
5875
- };
5876
-
5877
- var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
5878
-
5879
- var Position = {
5880
- includeScrollOffsets: false,
5881
-
5882
- prepare: function() {
5883
- this.deltaX = window.pageXOffset
5884
- || document.documentElement.scrollLeft
5885
- || document.body.scrollLeft
5886
- || 0;
5887
- this.deltaY = window.pageYOffset
5888
- || document.documentElement.scrollTop
5889
- || document.body.scrollTop
5890
- || 0;
5891
- },
5892
-
5893
- within: function(element, x, y) {
5894
- if (this.includeScrollOffsets)
5895
- return this.withinIncludingScrolloffsets(element, x, y);
5896
- this.xcomp = x;
5897
- this.ycomp = y;
5898
- this.offset = Element.cumulativeOffset(element);
5899
-
5900
- return (y >= this.offset[1] &&
5901
- y < this.offset[1] + element.offsetHeight &&
5902
- x >= this.offset[0] &&
5903
- x < this.offset[0] + element.offsetWidth);
5904
- },
5905
-
5906
- withinIncludingScrolloffsets: function(element, x, y) {
5907
- var offsetcache = Element.cumulativeScrollOffset(element);
5908
-
5909
- this.xcomp = x + offsetcache[0] - this.deltaX;
5910
- this.ycomp = y + offsetcache[1] - this.deltaY;
5911
- this.offset = Element.cumulativeOffset(element);
5912
-
5913
- return (this.ycomp >= this.offset[1] &&
5914
- this.ycomp < this.offset[1] + element.offsetHeight &&
5915
- this.xcomp >= this.offset[0] &&
5916
- this.xcomp < this.offset[0] + element.offsetWidth);
5917
- },
5918
-
5919
- overlap: function(mode, element) {
5920
- if (!mode) return 0;
5921
- if (mode == 'vertical')
5922
- return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
5923
- element.offsetHeight;
5924
- if (mode == 'horizontal')
5925
- return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
5926
- element.offsetWidth;
5927
- },
5928
-
5929
-
5930
- cumulativeOffset: Element.Methods.cumulativeOffset,
5931
-
5932
- positionedOffset: Element.Methods.positionedOffset,
5933
-
5934
- absolutize: function(element) {
5935
- Position.prepare();
5936
- return Element.absolutize(element);
5937
- },
5938
-
5939
- relativize: function(element) {
5940
- Position.prepare();
5941
- return Element.relativize(element);
5942
- },
5943
-
5944
- realOffset: Element.Methods.cumulativeScrollOffset,
5945
-
5946
- offsetParent: Element.Methods.getOffsetParent,
5947
-
5948
- page: Element.Methods.viewportOffset,
5949
-
5950
- clone: function(source, target, options) {
5951
- options = options || { };
5952
- return Element.clonePosition(target, source, options);
5953
- }
5954
- };
5955
-
5956
- /*--------------------------------------------------------------------------*/
5957
-
5958
- if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
5959
- function iter(name) {
5960
- return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
5961
- }
5962
-
5963
- instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
5964
- function(element, className) {
5965
- className = className.toString().strip();
5966
- var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
5967
- return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
5968
- } : function(element, className) {
5969
- className = className.toString().strip();
5970
- var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
5971
- if (!classNames && !className) return elements;
5972
-
5973
- var nodes = $(element).getElementsByTagName('*');
5974
- className = ' ' + className + ' ';
5975
-
5976
- for (var i = 0, child, cn; child = nodes[i]; i++) {
5977
- if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
5978
- (classNames && classNames.all(function(name) {
5979
- return !name.toString().blank() && cn.include(' ' + name + ' ');
5980
- }))))
5981
- elements.push(Element.extend(child));
5982
- }
5983
- return elements;
5984
- };
5985
-
5986
- return function(className, parentElement) {
5987
- return $(parentElement || document.body).getElementsByClassName(className);
5988
- };
5989
- }(Element.Methods);
5990
-
5991
- /*--------------------------------------------------------------------------*/
5992
-
5993
- Element.ClassNames = Class.create();
5994
- Element.ClassNames.prototype = {
5995
- initialize: function(element) {
5996
- this.element = $(element);
5997
- },
5998
-
5999
- _each: function(iterator) {
6000
- this.element.className.split(/\s+/).select(function(name) {
6001
- return name.length > 0;
6002
- })._each(iterator);
6003
- },
6004
-
6005
- set: function(className) {
6006
- this.element.className = className;
6007
- },
6008
-
6009
- add: function(classNameToAdd) {
6010
- if (this.include(classNameToAdd)) return;
6011
- this.set($A(this).concat(classNameToAdd).join(' '));
6012
- },
6013
-
6014
- remove: function(classNameToRemove) {
6015
- if (!this.include(classNameToRemove)) return;
6016
- this.set($A(this).without(classNameToRemove).join(' '));
6017
- },
6018
-
6019
- toString: function() {
6020
- return $A(this).join(' ');
6021
- }
6022
- };
6023
-
6024
- Object.extend(Element.ClassNames.prototype, Enumerable);
6025
-
6026
- /*--------------------------------------------------------------------------*/
6027
-
6028
- (function() {
6029
- window.Selector = Class.create({
6030
- initialize: function(expression) {
6031
- this.expression = expression.strip();
6032
- },
6033
-
6034
- findElements: function(rootElement) {
6035
- return Prototype.Selector.select(this.expression, rootElement);
6036
- },
6037
-
6038
- match: function(element) {
6039
- return Prototype.Selector.match(element, this.expression);
6040
- },
6041
-
6042
- toString: function() {
6043
- return this.expression;
6044
- },
6045
-
6046
- inspect: function() {
6047
- return "#<Selector: " + this.expression + ">";
6048
- }
6049
- });
6050
-
6051
- Object.extend(Selector, {
6052
- matchElements: function(elements, expression) {
6053
- var match = Prototype.Selector.match,
6054
- results = [];
6055
-
6056
- for (var i = 0, length = elements.length; i < length; i++) {
6057
- var element = elements[i];
6058
- if (match(element, expression)) {
6059
- results.push(Element.extend(element));
6060
- }
6061
- }
6062
- return results;
6063
- },
6064
-
6065
- findElement: function(elements, expression, index) {
6066
- index = index || 0;
6067
- var matchIndex = 0, element;
6068
- for (var i = 0, length = elements.length; i < length; i++) {
6069
- element = elements[i];
6070
- if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
6071
- return Element.extend(element);
6072
- }
6073
- }
6074
- },
6075
-
6076
- findChildElements: function(element, expressions) {
6077
- var selector = expressions.toArray().join(', ');
6078
- return Prototype.Selector.select(selector, element || document);
6079
- }
6080
- });
6081
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/scriptaculous.js DELETED
@@ -1,68 +0,0 @@
1
- // script.aculo.us scriptaculous.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- //
5
- // Permission is hereby granted, free of charge, to any person obtaining
6
- // a copy of this software and associated documentation files (the
7
- // "Software"), to deal in the Software without restriction, including
8
- // without limitation the rights to use, copy, modify, merge, publish,
9
- // distribute, sublicense, and/or sell copies of the Software, and to
10
- // permit persons to whom the Software is furnished to do so, subject to
11
- // the following conditions:
12
- //
13
- // The above copyright notice and this permission notice shall be
14
- // included in all copies or substantial portions of the Software.
15
- //
16
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
- //
24
- // For details, see the script.aculo.us web site: http://script.aculo.us/
25
-
26
- var Scriptaculous = {
27
- Version: '1.9.0',
28
- require: function(libraryName) {
29
- try{
30
- // inserting via DOM fails in Safari 2.0, so brute force approach
31
- document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
32
- } catch(e) {
33
- // for xhtml+xml served content, fall back to DOM methods
34
- var script = document.createElement('script');
35
- script.type = 'text/javascript';
36
- script.src = libraryName;
37
- document.getElementsByTagName('head')[0].appendChild(script);
38
- }
39
- },
40
- REQUIRED_PROTOTYPE: '1.6.0.3',
41
- load: function() {
42
- function convertVersionString(versionString) {
43
- var v = versionString.replace(/_.*|\./g, '');
44
- v = parseInt(v + '0'.times(4-v.length));
45
- return versionString.indexOf('_') > -1 ? v-1 : v;
46
- }
47
-
48
- if((typeof Prototype=='undefined') ||
49
- (typeof Element == 'undefined') ||
50
- (typeof Element.Methods=='undefined') ||
51
- (convertVersionString(Prototype.Version) <
52
- convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
53
- throw("script.aculo.us requires the Prototype JavaScript framework >= " +
54
- Scriptaculous.REQUIRED_PROTOTYPE);
55
-
56
- var js = /scriptaculous\.js(\?.*)?$/;
57
- $$('script[src]').findAll(function(s) {
58
- return s.src.match(js);
59
- }).each(function(s) {
60
- var path = s.src.replace(js, ''),
61
- includes = s.src.match(/\?.*load=([a-z,]*)/);
62
- (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
63
- function(include) { Scriptaculous.require(path+include+'.js') });
64
- });
65
- }
66
- };
67
-
68
- Scriptaculous.load();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/slider.js DELETED
@@ -1,275 +0,0 @@
1
- // script.aculo.us slider.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Marty Haught, Thomas Fuchs
4
- //
5
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
6
- // For details, see the script.aculo.us web site: http://script.aculo.us/
7
-
8
- if (!Control) var Control = { };
9
-
10
- // options:
11
- // axis: 'vertical', or 'horizontal' (default)
12
- //
13
- // callbacks:
14
- // onChange(value)
15
- // onSlide(value)
16
- Control.Slider = Class.create({
17
- initialize: function(handle, track, options) {
18
- var slider = this;
19
-
20
- if (Object.isArray(handle)) {
21
- this.handles = handle.collect( function(e) { return $(e) });
22
- } else {
23
- this.handles = [$(handle)];
24
- }
25
-
26
- this.track = $(track);
27
- this.options = options || { };
28
-
29
- this.axis = this.options.axis || 'horizontal';
30
- this.increment = this.options.increment || 1;
31
- this.step = parseInt(this.options.step || '1');
32
- this.range = this.options.range || $R(0,1);
33
-
34
- this.value = 0; // assure backwards compat
35
- this.values = this.handles.map( function() { return 0 });
36
- this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
37
- this.options.startSpan = $(this.options.startSpan || null);
38
- this.options.endSpan = $(this.options.endSpan || null);
39
-
40
- this.restricted = this.options.restricted || false;
41
-
42
- this.maximum = this.options.maximum || this.range.end;
43
- this.minimum = this.options.minimum || this.range.start;
44
-
45
- // Will be used to align the handle onto the track, if necessary
46
- this.alignX = parseInt(this.options.alignX || '0');
47
- this.alignY = parseInt(this.options.alignY || '0');
48
-
49
- this.trackLength = this.maximumOffset() - this.minimumOffset();
50
-
51
- this.handleLength = this.isVertical() ?
52
- (this.handles[0].offsetHeight != 0 ?
53
- this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
54
- (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
55
- this.handles[0].style.width.replace(/px$/,""));
56
-
57
- this.active = false;
58
- this.dragging = false;
59
- this.disabled = false;
60
-
61
- if (this.options.disabled) this.setDisabled();
62
-
63
- // Allowed values array
64
- this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
65
- if (this.allowedValues) {
66
- this.minimum = this.allowedValues.min();
67
- this.maximum = this.allowedValues.max();
68
- }
69
-
70
- this.eventMouseDown = this.startDrag.bindAsEventListener(this);
71
- this.eventMouseUp = this.endDrag.bindAsEventListener(this);
72
- this.eventMouseMove = this.update.bindAsEventListener(this);
73
-
74
- // Initialize handles in reverse (make sure first handle is active)
75
- this.handles.each( function(h,i) {
76
- i = slider.handles.length-1-i;
77
- slider.setValue(parseFloat(
78
- (Object.isArray(slider.options.sliderValue) ?
79
- slider.options.sliderValue[i] : slider.options.sliderValue) ||
80
- slider.range.start), i);
81
- h.makePositioned().observe("mousedown", slider.eventMouseDown);
82
- });
83
-
84
- this.track.observe("mousedown", this.eventMouseDown);
85
- document.observe("mouseup", this.eventMouseUp);
86
- document.observe("mousemove", this.eventMouseMove);
87
-
88
- this.initialized = true;
89
- },
90
- dispose: function() {
91
- var slider = this;
92
- Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
93
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
94
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
95
- this.handles.each( function(h) {
96
- Event.stopObserving(h, "mousedown", slider.eventMouseDown);
97
- });
98
- },
99
- setDisabled: function(){
100
- this.disabled = true;
101
- },
102
- setEnabled: function(){
103
- this.disabled = false;
104
- },
105
- getNearestValue: function(value){
106
- if (this.allowedValues){
107
- if (value >= this.allowedValues.max()) return(this.allowedValues.max());
108
- if (value <= this.allowedValues.min()) return(this.allowedValues.min());
109
-
110
- var offset = Math.abs(this.allowedValues[0] - value);
111
- var newValue = this.allowedValues[0];
112
- this.allowedValues.each( function(v) {
113
- var currentOffset = Math.abs(v - value);
114
- if (currentOffset <= offset){
115
- newValue = v;
116
- offset = currentOffset;
117
- }
118
- });
119
- return newValue;
120
- }
121
- if (value > this.range.end) return this.range.end;
122
- if (value < this.range.start) return this.range.start;
123
- return value;
124
- },
125
- setValue: function(sliderValue, handleIdx){
126
- if (!this.active) {
127
- this.activeHandleIdx = handleIdx || 0;
128
- this.activeHandle = this.handles[this.activeHandleIdx];
129
- this.updateStyles();
130
- }
131
- handleIdx = handleIdx || this.activeHandleIdx || 0;
132
- if (this.initialized && this.restricted) {
133
- if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
134
- sliderValue = this.values[handleIdx-1];
135
- if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
136
- sliderValue = this.values[handleIdx+1];
137
- }
138
- sliderValue = this.getNearestValue(sliderValue);
139
- this.values[handleIdx] = sliderValue;
140
- this.value = this.values[0]; // assure backwards compat
141
-
142
- this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
143
- this.translateToPx(sliderValue);
144
-
145
- this.drawSpans();
146
- if (!this.dragging || !this.event) this.updateFinished();
147
- },
148
- setValueBy: function(delta, handleIdx) {
149
- this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
150
- handleIdx || this.activeHandleIdx || 0);
151
- },
152
- translateToPx: function(value) {
153
- return Math.round(
154
- ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
155
- (value - this.range.start)) + "px";
156
- },
157
- translateToValue: function(offset) {
158
- return ((offset/(this.trackLength-this.handleLength) *
159
- (this.range.end-this.range.start)) + this.range.start);
160
- },
161
- getRange: function(range) {
162
- var v = this.values.sortBy(Prototype.K);
163
- range = range || 0;
164
- return $R(v[range],v[range+1]);
165
- },
166
- minimumOffset: function(){
167
- return(this.isVertical() ? this.alignY : this.alignX);
168
- },
169
- maximumOffset: function(){
170
- return(this.isVertical() ?
171
- (this.track.offsetHeight != 0 ? this.track.offsetHeight :
172
- this.track.style.height.replace(/px$/,"")) - this.alignY :
173
- (this.track.offsetWidth != 0 ? this.track.offsetWidth :
174
- this.track.style.width.replace(/px$/,"")) - this.alignX);
175
- },
176
- isVertical: function(){
177
- return (this.axis == 'vertical');
178
- },
179
- drawSpans: function() {
180
- var slider = this;
181
- if (this.spans)
182
- $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
183
- if (this.options.startSpan)
184
- this.setSpan(this.options.startSpan,
185
- $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
186
- if (this.options.endSpan)
187
- this.setSpan(this.options.endSpan,
188
- $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
189
- },
190
- setSpan: function(span, range) {
191
- if (this.isVertical()) {
192
- span.style.top = this.translateToPx(range.start);
193
- span.style.height = this.translateToPx(range.end - range.start + this.range.start);
194
- } else {
195
- span.style.left = this.translateToPx(range.start);
196
- span.style.width = this.translateToPx(range.end - range.start + this.range.start);
197
- }
198
- },
199
- updateStyles: function() {
200
- this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
201
- Element.addClassName(this.activeHandle, 'selected');
202
- },
203
- startDrag: function(event) {
204
- if (Event.isLeftClick(event)) {
205
- if (!this.disabled){
206
- this.active = true;
207
-
208
- var handle = Event.element(event);
209
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
210
- var track = handle;
211
- if (track==this.track) {
212
- var offsets = this.track.cumulativeOffset();
213
- this.event = event;
214
- this.setValue(this.translateToValue(
215
- (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
216
- ));
217
- var offsets = this.activeHandle.cumulativeOffset();
218
- this.offsetX = (pointer[0] - offsets[0]);
219
- this.offsetY = (pointer[1] - offsets[1]);
220
- } else {
221
- // find the handle (prevents issues with Safari)
222
- while((this.handles.indexOf(handle) == -1) && handle.parentNode)
223
- handle = handle.parentNode;
224
-
225
- if (this.handles.indexOf(handle)!=-1) {
226
- this.activeHandle = handle;
227
- this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
228
- this.updateStyles();
229
-
230
- var offsets = this.activeHandle.cumulativeOffset();
231
- this.offsetX = (pointer[0] - offsets[0]);
232
- this.offsetY = (pointer[1] - offsets[1]);
233
- }
234
- }
235
- }
236
- Event.stop(event);
237
- }
238
- },
239
- update: function(event) {
240
- if (this.active) {
241
- if (!this.dragging) this.dragging = true;
242
- this.draw(event);
243
- if (Prototype.Browser.WebKit) window.scrollBy(0,0);
244
- Event.stop(event);
245
- }
246
- },
247
- draw: function(event) {
248
- var pointer = [Event.pointerX(event), Event.pointerY(event)];
249
- var offsets = this.track.cumulativeOffset();
250
- pointer[0] -= this.offsetX + offsets[0];
251
- pointer[1] -= this.offsetY + offsets[1];
252
- this.event = event;
253
- this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
254
- if (this.initialized && this.options.onSlide)
255
- this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
256
- },
257
- endDrag: function(event) {
258
- if (this.active && this.dragging) {
259
- this.finishDrag(event, true);
260
- Event.stop(event);
261
- }
262
- this.active = false;
263
- this.dragging = false;
264
- },
265
- finishDrag: function(event, success) {
266
- this.active = false;
267
- this.dragging = false;
268
- this.updateFinished();
269
- },
270
- updateFinished: function() {
271
- if (this.initialized && this.options.onChange)
272
- this.options.onChange(this.values.length>1 ? this.values : this.value, this);
273
- this.event = null;
274
- }
275
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/sound.js DELETED
@@ -1,59 +0,0 @@
1
- // script.aculo.us sound.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- //
5
- // Based on code created by Jules Gravinese (http://www.webveteran.com/)
6
- //
7
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
8
- // For details, see the script.aculo.us web site: http://script.aculo.us/
9
-
10
- Sound = {
11
- tracks: {},
12
- _enabled: true,
13
- template:
14
- new Template('<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>'),
15
- enable: function(){
16
- Sound._enabled = true;
17
- },
18
- disable: function(){
19
- Sound._enabled = false;
20
- },
21
- play: function(url){
22
- if(!Sound._enabled) return;
23
- var options = Object.extend({
24
- track: 'global', url: url, replace: false
25
- }, arguments[1] || {});
26
-
27
- if(options.replace && this.tracks[options.track]) {
28
- $R(0, this.tracks[options.track].id).each(function(id){
29
- var sound = $('sound_'+options.track+'_'+id);
30
- sound.Stop && sound.Stop();
31
- sound.remove();
32
- });
33
- this.tracks[options.track] = null;
34
- }
35
-
36
- if(!this.tracks[options.track])
37
- this.tracks[options.track] = { id: 0 };
38
- else
39
- this.tracks[options.track].id++;
40
-
41
- options.id = this.tracks[options.track].id;
42
- $$('body')[0].insert(
43
- Prototype.Browser.IE ? new Element('bgsound',{
44
- id: 'sound_'+options.track+'_'+options.id,
45
- src: options.url, loop: 1, autostart: true
46
- }) : Sound.template.evaluate(options));
47
- }
48
- };
49
-
50
- if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
51
- if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
52
- Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>');
53
- else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('Windows Media') != -1 }))
54
- Sound.template = new Template('<object id="sound_#{track}_#{id}" type="application/x-mplayer2" data="#{url}"></object>');
55
- else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('RealPlayer') != -1 }))
56
- Sound.template = new Template('<embed type="audio/x-pn-realaudio-plugin" style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>');
57
- else
58
- Sound.play = function(){};
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/mageho/sortproducts/unittest.js DELETED
@@ -1,568 +0,0 @@
1
- // script.aculo.us unittest.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
2
-
3
- // Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
- // (c) 2005-2010 Jon Tirsen (http://www.tirsen.com)
5
- // (c) 2005-2010 Michael Schuerig (http://www.schuerig.de/michael/)
6
- //
7
- // script.aculo.us is freely distributable under the terms of an MIT-style license.
8
- // For details, see the script.aculo.us web site: http://script.aculo.us/
9
-
10
- // experimental, Firefox-only
11
- Event.simulateMouse = function(element, eventName) {
12
- var options = Object.extend({
13
- pointerX: 0,
14
- pointerY: 0,
15
- buttons: 0,
16
- ctrlKey: false,
17
- altKey: false,
18
- shiftKey: false,
19
- metaKey: false
20
- }, arguments[2] || {});
21
- var oEvent = document.createEvent("MouseEvents");
22
- oEvent.initMouseEvent(eventName, true, true, document.defaultView,
23
- options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
24
- options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
25
-
26
- if(this.mark) Element.remove(this.mark);
27
- this.mark = document.createElement('div');
28
- this.mark.appendChild(document.createTextNode(" "));
29
- document.body.appendChild(this.mark);
30
- this.mark.style.position = 'absolute';
31
- this.mark.style.top = options.pointerY + "px";
32
- this.mark.style.left = options.pointerX + "px";
33
- this.mark.style.width = "5px";
34
- this.mark.style.height = "5px;";
35
- this.mark.style.borderTop = "1px solid red;";
36
- this.mark.style.borderLeft = "1px solid red;";
37
-
38
- if(this.step)
39
- alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
40
-
41
- $(element).dispatchEvent(oEvent);
42
- };
43
-
44
- // Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
45
- // You need to downgrade to 1.0.4 for now to get this working
46
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
47
- Event.simulateKey = function(element, eventName) {
48
- var options = Object.extend({
49
- ctrlKey: false,
50
- altKey: false,
51
- shiftKey: false,
52
- metaKey: false,
53
- keyCode: 0,
54
- charCode: 0
55
- }, arguments[2] || {});
56
-
57
- var oEvent = document.createEvent("KeyEvents");
58
- oEvent.initKeyEvent(eventName, true, true, window,
59
- options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
60
- options.keyCode, options.charCode );
61
- $(element).dispatchEvent(oEvent);
62
- };
63
-
64
- Event.simulateKeys = function(element, command) {
65
- for(var i=0; i<command.length; i++) {
66
- Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
67
- }
68
- };
69
-
70
- var Test = {};
71
- Test.Unit = {};
72
-
73
- // security exception workaround
74
- Test.Unit.inspect = Object.inspect;
75
-
76
- Test.Unit.Logger = Class.create();
77
- Test.Unit.Logger.prototype = {
78
- initialize: function(log) {
79
- this.log = $(log);
80
- if (this.log) {
81
- this._createLogTable();
82
- }
83
- },
84
- start: function(testName) {
85
- if (!this.log) return;
86
- this.testName = testName;
87
- this.lastLogLine = document.createElement('tr');
88
- this.statusCell = document.createElement('td');
89
- this.nameCell = document.createElement('td');
90
- this.nameCell.className = "nameCell";
91
- this.nameCell.appendChild(document.createTextNode(testName));
92
- this.messageCell = document.createElement('td');
93
- this.lastLogLine.appendChild(this.statusCell);
94
- this.lastLogLine.appendChild(this.nameCell);
95
- this.lastLogLine.appendChild(this.messageCell);
96
- this.loglines.appendChild(this.lastLogLine);
97
- },
98
- finish: function(status, summary) {
99
- if (!this.log) return;
100
- this.lastLogLine.className = status;
101
- this.statusCell.innerHTML = status;
102
- this.messageCell.innerHTML = this._toHTML(summary);
103
- this.addLinksToResults();
104
- },
105
- message: function(message) {
106
- if (!this.log) return;
107
- this.messageCell.innerHTML = this._toHTML(message);
108
- },
109
- summary: function(summary) {
110
- if (!this.log) return;
111
- this.logsummary.innerHTML = this._toHTML(summary);
112
- },
113
- _createLogTable: function() {
114
- this.log.innerHTML =
115
- '<div id="logsummary"></div>' +
116
- '<table id="logtable">' +
117
- '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
118
- '<tbody id="loglines"></tbody>' +
119
- '</table>';
120
- this.logsummary = $('logsummary');
121
- this.loglines = $('loglines');
122
- },
123
- _toHTML: function(txt) {
124
- return txt.escapeHTML().replace(/\n/g,"<br/>");
125
- },
126
- addLinksToResults: function(){
127
- $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
128
- td.title = "Run only this test";
129
- Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
130
- });
131
- $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
132
- td.title = "Run all tests";
133
- Event.observe(td, 'click', function(){ window.location.search = "";});
134
- });
135
- }
136
- };
137
-
138
- Test.Unit.Runner = Class.create();
139
- Test.Unit.Runner.prototype = {
140
- initialize: function(testcases) {
141
- this.options = Object.extend({
142
- testLog: 'testlog'
143
- }, arguments[1] || {});
144
- this.options.resultsURL = this.parseResultsURLQueryParameter();
145
- this.options.tests = this.parseTestsQueryParameter();
146
- if (this.options.testLog) {
147
- this.options.testLog = $(this.options.testLog) || null;
148
- }
149
- if(this.options.tests) {
150
- this.tests = [];
151
- for(var i = 0; i < this.options.tests.length; i++) {
152
- if(/^test/.test(this.options.tests[i])) {
153
- this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
154
- }
155
- }
156
- } else {
157
- if (this.options.test) {
158
- this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
159
- } else {
160
- this.tests = [];
161
- for(var testcase in testcases) {
162
- if(/^test/.test(testcase)) {
163
- this.tests.push(
164
- new Test.Unit.Testcase(
165
- this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
166
- testcases[testcase], testcases["setup"], testcases["teardown"]
167
- ));
168
- }
169
- }
170
- }
171
- }
172
- this.currentTest = 0;
173
- this.logger = new Test.Unit.Logger(this.options.testLog);
174
- setTimeout(this.runTests.bind(this), 1000);
175
- },
176
- parseResultsURLQueryParameter: function() {
177
- return window.location.search.parseQuery()["resultsURL"];
178
- },
179
- parseTestsQueryParameter: function(){
180
- if (window.location.search.parseQuery()["tests"]){
181
- return window.location.search.parseQuery()["tests"].split(',');
182
- };
183
- },
184
- // Returns:
185
- // "ERROR" if there was an error,
186
- // "FAILURE" if there was a failure, or
187
- // "SUCCESS" if there was neither
188
- getResult: function() {
189
- var hasFailure = false;
190
- for(var i=0;i<this.tests.length;i++) {
191
- if (this.tests[i].errors > 0) {
192
- return "ERROR";
193
- }
194
- if (this.tests[i].failures > 0) {
195
- hasFailure = true;
196
- }
197
- }
198
- if (hasFailure) {
199
- return "FAILURE";
200
- } else {
201
- return "SUCCESS";
202
- }
203
- },
204
- postResults: function() {
205
- if (this.options.resultsURL) {
206
- new Ajax.Request(this.options.resultsURL,
207
- { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
208
- }
209
- },
210
- runTests: function() {
211
- var test = this.tests[this.currentTest];
212
- if (!test) {
213
- // finished!
214
- this.postResults();
215
- this.logger.summary(this.summary());
216
- return;
217
- }
218
- if(!test.isWaiting) {
219
- this.logger.start(test.name);
220
- }
221
- test.run();
222
- if(test.isWaiting) {
223
- this.logger.message("Waiting for " + test.timeToWait + "ms");
224
- setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
225
- } else {
226
- this.logger.finish(test.status(), test.summary());
227
- this.currentTest++;
228
- // tail recursive, hopefully the browser will skip the stackframe
229
- this.runTests();
230
- }
231
- },
232
- summary: function() {
233
- var assertions = 0;
234
- var failures = 0;
235
- var errors = 0;
236
- var messages = [];
237
- for(var i=0;i<this.tests.length;i++) {
238
- assertions += this.tests[i].assertions;
239
- failures += this.tests[i].failures;
240
- errors += this.tests[i].errors;
241
- }
242
- return (
243
- (this.options.context ? this.options.context + ': ': '') +
244
- this.tests.length + " tests, " +
245
- assertions + " assertions, " +
246
- failures + " failures, " +
247
- errors + " errors");
248
- }
249
- };
250
-
251
- Test.Unit.Assertions = Class.create();
252
- Test.Unit.Assertions.prototype = {
253
- initialize: function() {
254
- this.assertions = 0;
255
- this.failures = 0;
256
- this.errors = 0;
257
- this.messages = [];
258
- },
259
- summary: function() {
260
- return (
261
- this.assertions + " assertions, " +
262
- this.failures + " failures, " +
263
- this.errors + " errors" + "\n" +
264
- this.messages.join("\n"));
265
- },
266
- pass: function() {
267
- this.assertions++;
268
- },
269
- fail: function(message) {
270
- this.failures++;
271
- this.messages.push("Failure: " + message);
272
- },
273
- info: function(message) {
274
- this.messages.push("Info: " + message);
275
- },
276
- error: function(error) {
277
- this.errors++;
278
- this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
279
- },
280
- status: function() {
281
- if (this.failures > 0) return 'failed';
282
- if (this.errors > 0) return 'error';
283
- return 'passed';
284
- },
285
- assert: function(expression) {
286
- var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
287
- try { expression ? this.pass() :
288
- this.fail(message); }
289
- catch(e) { this.error(e); }
290
- },
291
- assertEqual: function(expected, actual) {
292
- var message = arguments[2] || "assertEqual";
293
- try { (expected == actual) ? this.pass() :
294
- this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
295
- '", actual "' + Test.Unit.inspect(actual) + '"'); }
296
- catch(e) { this.error(e); }
297
- },
298
- assertInspect: function(expected, actual) {
299
- var message = arguments[2] || "assertInspect";
300
- try { (expected == actual.inspect()) ? this.pass() :
301
- this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
302
- '", actual "' + Test.Unit.inspect(actual) + '"'); }
303
- catch(e) { this.error(e); }
304
- },
305
- assertEnumEqual: function(expected, actual) {
306
- var message = arguments[2] || "assertEnumEqual";
307
- try { $A(expected).length == $A(actual).length &&
308
- expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
309
- this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
310
- ', actual ' + Test.Unit.inspect(actual)); }
311
- catch(e) { this.error(e); }
312
- },
313
- assertNotEqual: function(expected, actual) {
314
- var message = arguments[2] || "assertNotEqual";
315
- try { (expected != actual) ? this.pass() :
316
- this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
317
- catch(e) { this.error(e); }
318
- },
319
- assertIdentical: function(expected, actual) {
320
- var message = arguments[2] || "assertIdentical";
321
- try { (expected === actual) ? this.pass() :
322
- this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
323
- '", actual "' + Test.Unit.inspect(actual) + '"'); }
324
- catch(e) { this.error(e); }
325
- },
326
- assertNotIdentical: function(expected, actual) {
327
- var message = arguments[2] || "assertNotIdentical";
328
- try { !(expected === actual) ? this.pass() :
329
- this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
330
- '", actual "' + Test.Unit.inspect(actual) + '"'); }
331
- catch(e) { this.error(e); }
332
- },
333
- assertNull: function(obj) {
334
- var message = arguments[1] || 'assertNull';
335
- try { (obj==null) ? this.pass() :
336
- this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
337
- catch(e) { this.error(e); }
338
- },
339
- assertMatch: function(expected, actual) {
340
- var message = arguments[2] || 'assertMatch';
341
- var regex = new RegExp(expected);
342
- try { (regex.exec(actual)) ? this.pass() :
343
- this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
344
- catch(e) { this.error(e); }
345
- },
346
- assertHidden: function(element) {
347
- var message = arguments[1] || 'assertHidden';
348
- this.assertEqual("none", element.style.display, message);
349
- },
350
- assertNotNull: function(object) {
351
- var message = arguments[1] || 'assertNotNull';
352
- this.assert(object != null, message);
353
- },
354
- assertType: function(expected, actual) {
355
- var message = arguments[2] || 'assertType';
356
- try {
357
- (actual.constructor == expected) ? this.pass() :
358
- this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
359
- '", actual "' + (actual.constructor) + '"'); }
360
- catch(e) { this.error(e); }
361
- },
362
- assertNotOfType: function(expected, actual) {
363
- var message = arguments[2] || 'assertNotOfType';
364
- try {
365
- (actual.constructor != expected) ? this.pass() :
366
- this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
367
- '", actual "' + (actual.constructor) + '"'); }
368
- catch(e) { this.error(e); }
369
- },
370
- assertInstanceOf: function(expected, actual) {
371
- var message = arguments[2] || 'assertInstanceOf';
372
- try {
373
- (actual instanceof expected) ? this.pass() :
374
- this.fail(message + ": object was not an instance of the expected type"); }
375
- catch(e) { this.error(e); }
376
- },
377
- assertNotInstanceOf: function(expected, actual) {
378
- var message = arguments[2] || 'assertNotInstanceOf';
379
- try {
380
- !(actual instanceof expected) ? this.pass() :
381
- this.fail(message + ": object was an instance of the not expected type"); }
382
- catch(e) { this.error(e); }
383
- },
384
- assertRespondsTo: function(method, obj) {
385
- var message = arguments[2] || 'assertRespondsTo';
386
- try {
387
- (obj[method] && typeof obj[method] == 'function') ? this.pass() :
388
- this.fail(message + ": object doesn't respond to [" + method + "]"); }
389
- catch(e) { this.error(e); }
390
- },
391
- assertReturnsTrue: function(method, obj) {
392
- var message = arguments[2] || 'assertReturnsTrue';
393
- try {
394
- var m = obj[method];
395
- if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
396
- m() ? this.pass() :
397
- this.fail(message + ": method returned false"); }
398
- catch(e) { this.error(e); }
399
- },
400
- assertReturnsFalse: function(method, obj) {
401
- var message = arguments[2] || 'assertReturnsFalse';
402
- try {
403
- var m = obj[method];
404
- if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
405
- !m() ? this.pass() :
406
- this.fail(message + ": method returned true"); }
407
- catch(e) { this.error(e); }
408
- },
409
- assertRaise: function(exceptionName, method) {
410
- var message = arguments[2] || 'assertRaise';
411
- try {
412
- method();
413
- this.fail(message + ": exception expected but none was raised"); }
414
- catch(e) {
415
- ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e);
416
- }
417
- },
418
- assertElementsMatch: function() {
419
- var expressions = $A(arguments), elements = $A(expressions.shift());
420
- if (elements.length != expressions.length) {
421
- this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
422
- return false;
423
- }
424
- elements.zip(expressions).all(function(pair, index) {
425
- var element = $(pair.first()), expression = pair.last();
426
- if (element.match(expression)) return true;
427
- this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
428
- }.bind(this)) && this.pass();
429
- },
430
- assertElementMatches: function(element, expression) {
431
- this.assertElementsMatch([element], expression);
432
- },
433
- benchmark: function(operation, iterations) {
434
- var startAt = new Date();
435
- (iterations || 1).times(operation);
436
- var timeTaken = ((new Date())-startAt);
437
- this.info((arguments[2] || 'Operation') + ' finished ' +
438
- iterations + ' iterations in ' + (timeTaken/1000)+'s' );
439
- return timeTaken;
440
- },
441
- _isVisible: function(element) {
442
- element = $(element);
443
- if(!element.parentNode) return true;
444
- this.assertNotNull(element);
445
- if(element.style && Element.getStyle(element, 'display') == 'none')
446
- return false;
447
-
448
- return this._isVisible(element.parentNode);
449
- },
450
- assertNotVisible: function(element) {
451
- this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
452
- },
453
- assertVisible: function(element) {
454
- this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
455
- },
456
- benchmark: function(operation, iterations) {
457
- var startAt = new Date();
458
- (iterations || 1).times(operation);
459
- var timeTaken = ((new Date())-startAt);
460
- this.info((arguments[2] || 'Operation') + ' finished ' +
461
- iterations + ' iterations in ' + (timeTaken/1000)+'s' );
462
- return timeTaken;
463
- }
464
- };
465
-
466
- Test.Unit.Testcase = Class.create();
467
- Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
468
- initialize: function(name, test, setup, teardown) {
469
- Test.Unit.Assertions.prototype.initialize.bind(this)();
470
- this.name = name;
471
-
472
- if(typeof test == 'string') {
473
- test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
474
- test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
475
- this.test = function() {
476
- eval('with(this){'+test+'}');
477
- }
478
- } else {
479
- this.test = test || function() {};
480
- }
481
-
482
- this.setup = setup || function() {};
483
- this.teardown = teardown || function() {};
484
- this.isWaiting = false;
485
- this.timeToWait = 1000;
486
- },
487
- wait: function(time, nextPart) {
488
- this.isWaiting = true;
489
- this.test = nextPart;
490
- this.timeToWait = time;
491
- },
492
- run: function() {
493
- try {
494
- try {
495
- if (!this.isWaiting) this.setup.bind(this)();
496
- this.isWaiting = false;
497
- this.test.bind(this)();
498
- } finally {
499
- if(!this.isWaiting) {
500
- this.teardown.bind(this)();
501
- }
502
- }
503
- }
504
- catch(e) { this.error(e); }
505
- }
506
- });
507
-
508
- // *EXPERIMENTAL* BDD-style testing to please non-technical folk
509
- // This draws many ideas from RSpec http://rspec.rubyforge.org/
510
-
511
- Test.setupBDDExtensionMethods = function(){
512
- var METHODMAP = {
513
- shouldEqual: 'assertEqual',
514
- shouldNotEqual: 'assertNotEqual',
515
- shouldEqualEnum: 'assertEnumEqual',
516
- shouldBeA: 'assertType',
517
- shouldNotBeA: 'assertNotOfType',
518
- shouldBeAn: 'assertType',
519
- shouldNotBeAn: 'assertNotOfType',
520
- shouldBeNull: 'assertNull',
521
- shouldNotBeNull: 'assertNotNull',
522
-
523
- shouldBe: 'assertReturnsTrue',
524
- shouldNotBe: 'assertReturnsFalse',
525
- shouldRespondTo: 'assertRespondsTo'
526
- };
527
- var makeAssertion = function(assertion, args, object) {
528
- this[assertion].apply(this,(args || []).concat([object]));
529
- };
530
-
531
- Test.BDDMethods = {};
532
- $H(METHODMAP).each(function(pair) {
533
- Test.BDDMethods[pair.key] = function() {
534
- var args = $A(arguments);
535
- var scope = args.shift();
536
- makeAssertion.apply(scope, [pair.value, args, this]); };
537
- });
538
-
539
- [Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each(
540
- function(p){ Object.extend(p, Test.BDDMethods) }
541
- );
542
- };
543
-
544
- Test.context = function(name, spec, log){
545
- Test.setupBDDExtensionMethods();
546
-
547
- var compiledSpec = {};
548
- var titles = {};
549
- for(specName in spec) {
550
- switch(specName){
551
- case "setup":
552
- case "teardown":
553
- compiledSpec[specName] = spec[specName];
554
- break;
555
- default:
556
- var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
557
- var body = spec[specName].toString().split('\n').slice(1);
558
- if(/^\{/.test(body[0])) body = body.slice(1);
559
- body.pop();
560
- body = body.map(function(statement){
561
- return statement.strip()
562
- });
563
- compiledSpec[testName] = body.join('\n');
564
- titles[testName] = specName;
565
- }
566
- }
567
- new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: log || 'testlog', context: name });
568
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Mageho_Sortproducts</name>
4
- <version>1.0.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0 : Open Software License</license>
7
  <channel>community</channel>
@@ -56,9 +56,9 @@
56
  &lt;/ul&gt;</description>
57
  <notes>Initial Release</notes>
58
  <authors><author><name>Ilan PARMENTIER</name><user>Mageho</user><email>ilan.parmentier@mageho.com</email></author></authors>
59
- <date>2013-05-07</date>
60
- <time>17:15:18</time>
61
- <contents><target name="magelocale"><dir name="fr_FR"><file name="Mageho_All.csv" hash="e4f2394435fea990e3f6b1ec968c7273"/><file name="Mageho_Sortproducts.csv" hash="2b75d031a008ee52024ee56281bdf7c3"/></dir></target><target name="mageetc"><dir name="modules"><file name="Mageho_All.xml" hash="92fbf727ce4c64233605ee7276525aed"/><file name="Mageho_Sortproducts.xml" hash="777c7b7f72d78e719eda6c2bbe36b690"/></dir></target><target name="magelocal"><dir name="Mageho"><dir name="All"><dir name="Block"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Fieldset"><file name="Extensions.php" hash="3cb049b292385aa84dff14c1472d41eb"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="1f1f8a668f52a26a72df6cfbead6485a"/></dir><dir name="etc"><file name="adminhtml.xml" hash="602adc885b83b88416ab50aced3fc207"/><file name="config.xml" hash="1401e67c17ac1d86daddcdeafca395ef"/><file name="system.xml" hash="3baf3a1ebb1105e7c7260cdcb8a96f9b"/></dir></dir><dir name="Sortproducts"><dir name="Block"><dir name="Adminhtml"><file name="Info.php" hash="d718fada1ab919b5ac6286fda50964bb"/><file name="Info.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/><file name="Sortgrid.php" hash="3cf9c9f27e9bbf893356191072303f3c"/><file name="Sortgrid.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/><file name="Tab.php" hash="4467d5a3fae44d8f9bf74a6769d2c6a8"/><file name="Tab.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/></dir></dir><dir name="Helper"><file name="Data.php" hash="9e24dbfee79b96f5a29692bf132e2ac8"/><file name="Data.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/></dir><dir name="Model"><file name="Observer.php" hash="82f727e0ae154da87afceb6738313945"/><file name="Observer.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/><dir name="Resource"><file name="Position.php" hash="ad41c330a19fed4ea7945c987d0fcf10"/><file name="Position.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Attributes.php" hash="8e5dd4240d07df4a99fb89578bd4e09a"/><file name="Attributes.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Mageho"><file name="SortproductsController.php" hash="e0786efd1f2557fed892f8f6a4f67dd4"/><file name="SortproductsController.php.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="732d750e132a184dd0027d49fd4f2de0"/><file name="adminhtml.xml.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/><file name="config.xml" hash="d95c26d38a352fa17b966ad50ace437c"/><file name="config.xml.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/><file name="system.xml" hash="7a3bfbdea4e5cff6e383b50a0e563a35"/><file name="system.xml.LCK" hash="091b90ac6be764824a9fa6f1939caaab"/></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="mageho"><dir name="sortproducts"><file name="placeholder.jpg" hash="b2b682d28a08a748a73d2cda70ab5a57"/><file name="sortproducts.css" hash="0939b00bf328fcb7f6b7f85e61876a3f"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="mageho"><file name="sortproducts.xml" hash="e87237697705cb433ea5705656162b75"/></dir></dir><dir name="template"><dir name="mageho"><dir name="sortproducts"><file name="info.phtml" hash="45583e4d8b832206e8c436fe6c41d501"/><file name="sortgrid.phtml" hash="c0b79247a7ac8511cb858aacda6351a9"/><file name="tab.phtml" hash="d55081f3fcbe8ef3d0faba8ec50debe2"/></dir></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="mageho"><dir name="sortproducts"><file name="builder.js" hash="c6321f204481f259724bd6455c0fdded"/><file name="controls.js" hash="03b502fd8ae202eb164b348749392720"/><file name="dragdrop.js" hash="046759400db7a6096376e50110104edd"/><file name="effects.js" hash="0dea24894889a4c537e1a451a35f03ca"/><file name="excanvas.js" hash="9d9cbb230cf8d560faf6f6b0f6b5a7ce"/><file name="loading.gif" hash="505aa41462b8840208e1a7d810eb6f48"/><file name="opentip.css" hash="27c49d652671d27a22d91ba32f22ba42"/><file name="opentip.js" hash="5ed35816281e22b7e8b84ba7fdee9485"/><file name="prototype.js" hash="007ae2fe795811f80cedf92fdb591c1b"/><file name="scriptaculous.js" hash="bb679d586e7fccb154156baaef9dfde5"/><file name="slider.js" hash="a9e58cc5f8dd281daa8d8dfee6a78834"/><file name="sound.js" hash="0b22e4379d79b33b696ee3cccf2827b5"/><file name="unittest.js" hash="07c049c24cb838939925425bb555cdf6"/></dir></dir></dir></target></contents>
62
  <compatible/>
63
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
64
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Mageho_Sortproducts</name>
4
+ <version>1.0.2</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0 : Open Software License</license>
7
  <channel>community</channel>
56
  &lt;/ul&gt;</description>
57
  <notes>Initial Release</notes>
58
  <authors><author><name>Ilan PARMENTIER</name><user>Mageho</user><email>ilan.parmentier@mageho.com</email></author></authors>
59
+ <date>2013-05-19</date>
60
+ <time>20:44:25</time>
61
+ <contents><target name="magelocale"><dir name="fr_FR"><file name="Mageho_Sortproducts.csv" hash=""/></dir></target><target name="mageetc"><dir name="modules"><file name="Mageho_Sortproducts.xml" hash=""/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="mageho"><dir name="sortproducts"><file name="placeholder.jpg" hash="b2b682d28a08a748a73d2cda70ab5a57"/><file name="sortproducts.css" hash="0939b00bf328fcb7f6b7f85e61876a3f"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="mageho"><file name="sortproducts.xml" hash=""/></dir></dir></dir></dir></dir></target></contents>
62
  <compatible/>
63
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
64
  </package>