Version Notes
Initial release
Download this release
Release Info
Developer | Magento Core Team |
Extension | Eabi_Livehandler |
Version | 0.1.1 |
Comparing to | |
See all releases |
Version 0.1.1
- app/code/community/Eabi/Livehandler/Block/Adminhtml/Config/Form/Field/Button.php +57 -0
- app/code/community/Eabi/Livehandler/Block/Adminhtml/Config/Form/Field/Remove.php +89 -0
- app/code/community/Eabi/Livehandler/Block/Footer.php +166 -0
- app/code/community/Eabi/Livehandler/CHANGELOG.txt +3 -0
- app/code/community/Eabi/Livehandler/Helper/Data.php +172 -0
- app/code/community/Eabi/Livehandler/LICENCE.txt +1 -0
- app/code/community/Eabi/Livehandler/Model/Abstract.php +55 -0
- app/code/community/Eabi/Livehandler/Model/Action/Abstract.php +88 -0
- app/code/community/Eabi/Livehandler/Model/Adminhtml/Gridmanager.php +101 -0
- app/code/community/Eabi/Livehandler/Model/Entry.php +99 -0
- app/code/community/Eabi/Livehandler/Model/Mysql4/Entry.php +41 -0
- app/code/community/Eabi/Livehandler/Model/Mysql4/Entry/Collection.php +63 -0
- app/code/community/Eabi/Livehandler/Model/Ordergrid.php +814 -0
- app/code/community/Eabi/Livehandler/Model/System/Config/Backend/Button.php +127 -0
- app/code/community/Eabi/Livehandler/controllers/Adminhtml/LivehandlerController.php +109 -0
- app/code/community/Eabi/Livehandler/controllers/Adminhtml/RemoveController.php +67 -0
- app/code/community/Eabi/Livehandler/controllers/IndexController.php +102 -0
- app/code/community/Eabi/Livehandler/etc/config.xml +169 -0
- app/code/community/Eabi/Livehandler/etc/system.xml +107 -0
- app/code/community/Eabi/Livehandler/sql/eabi_livehandler_setup/mysql4-install-0.1.0.php +58 -0
- app/code/community/Eabi/Livehandler/sql/eabi_livehandler_setup/mysql4-upgrade-0.1.0-0.1.1.php +50 -0
- app/design/adminhtml/default/default/layout/eabi_livehandler.xml +32 -0
- app/design/frontend/base/default/layout/eabi_livehandler.xml +16 -0
- app/design/frontend/default/default/layout/eabi_livehandler.xml +16 -0
- app/etc/modules/Eabi_Livehandler.xml +21 -0
- app/locale/en_US/Eabi_Livehandler.csv +19 -0
- app/locale/et_EE/Eabi_Livehandler.csv +19 -0
- app/locale/fi_FI/Eabi_Livehandler.csv +19 -0
- app/locale/lt_LT/Eabi_Livehandler.csv +19 -0
- app/locale/sv_SE/Eabi_Livehandler.csv +19 -0
- js/eabi_js/crossBrowser_initKeyboardEvent.js +31 -0
- js/livepipe/contextmenu.js +185 -0
- js/livepipe/cookie.js +41 -0
- js/livepipe/event_behavior.js +298 -0
- js/livepipe/hotkey.js +74 -0
- js/livepipe/livepipe.js +181 -0
- js/livepipe/progressbar.js +102 -0
- js/livepipe/rating.js +156 -0
- js/livepipe/resizable.js +233 -0
- js/livepipe/scrollbar.js +227 -0
- js/livepipe/selection.js +459 -0
- js/livepipe/selectmultiple.js +155 -0
- js/livepipe/tabs.js +233 -0
- js/livepipe/textarea.js +122 -0
- js/livepipe/window.js +947 -0
- package.xml +22 -0
- skin/adminhtml/default/default/eabi_admintools.css +169 -0
app/code/community/Eabi/Livehandler/Block/Adminhtml/Config/Form/Field/Button.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Button
|
30 |
+
*
|
31 |
+
* @author Matis
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Block_Adminhtml_Config_Form_Field_Button extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract {
|
34 |
+
|
35 |
+
public function __construct() {
|
36 |
+
$this->addColumn('button_name', array(
|
37 |
+
'label' => Mage::helper('eabi_livehandler')->__('Button name'),
|
38 |
+
'style' => 'width:120px',
|
39 |
+
'class' => 'validate-code',
|
40 |
+
));
|
41 |
+
$this->addColumn('sort_order', array(
|
42 |
+
'label' => Mage::helper('adminhtml')->__('Sort order'),
|
43 |
+
'style' => 'width:120px',
|
44 |
+
'class' => 'validate-digits',
|
45 |
+
));
|
46 |
+
$this->addColumn('disabled', array(
|
47 |
+
'label' => Mage::helper('adminhtml')->__('Disabled'),
|
48 |
+
'style' => 'width:120px',
|
49 |
+
'class' => 'validate-digits-range digits-range-0-1',
|
50 |
+
));
|
51 |
+
$this->_addAfter = false;
|
52 |
+
$this->_addButtonLabel = Mage::helper('eabi_livehandler')->__('Add button');
|
53 |
+
parent::__construct();
|
54 |
+
}
|
55 |
+
|
56 |
+
}
|
57 |
+
|
app/code/community/Eabi/Livehandler/Block/Adminhtml/Config/Form/Field/Remove.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Button
|
30 |
+
*
|
31 |
+
* @author Matis
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Block_Adminhtml_Config_Form_Field_Remove extends Mage_Adminhtml_Block_System_Config_Form_Field {
|
34 |
+
|
35 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
|
36 |
+
$divId = $element->getId();
|
37 |
+
$helper = Mage::helper('eabi_livehandler');
|
38 |
+
$res = '';
|
39 |
+
$dirName = Mage::getBaseDir('code') . '/local/Eabi/Livehandler';
|
40 |
+
if (is_dir($dirName) && file_exists($dirName.'/etc/config.xml')) {
|
41 |
+
$res .= <<<HTML
|
42 |
+
<button class="scalable" id="{$divId}_button" type="button" onclick="{$divId}make_request(); return false;">{$helper->__('Delete instance of this module from %s folder', 'app/code/local')}</button>
|
43 |
+
|
44 |
+
HTML;
|
45 |
+
$res .= <<<HTML
|
46 |
+
<script type="text/javascript">
|
47 |
+
//<![CDATA[
|
48 |
+
|
49 |
+
function {$divId}make_request(actionName) {
|
50 |
+
var confirmR = confirm({$this->_toJson($helper->__('Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?', $dirName))});
|
51 |
+
|
52 |
+
if (confirmR) {
|
53 |
+
new Ajax.Request(
|
54 |
+
'{$this->getUrl('eabi_livehandler/adminhtml_remove/remove', array())}',
|
55 |
+
{
|
56 |
+
method: 'post',
|
57 |
+
asynchronous: true,
|
58 |
+
parameters: {"remove": "true"},
|
59 |
+
onSuccess: function(transport) {
|
60 |
+
var json = transport.responseText.evalJSON(true);
|
61 |
+
if (json['status'] && json['status'] == 'success') {
|
62 |
+
alert({$this->_toJson($helper->__('Folder %s deleted!', $dirName))});
|
63 |
+
\$({$this->_toJson($divId . '_button')}).hide();
|
64 |
+
} else {
|
65 |
+
alert({$this->_toJson($helper->__('Folder %s delete failed!', $dirName))});
|
66 |
+
}
|
67 |
+
},
|
68 |
+
onFailure: function(transport) {
|
69 |
+
alert(transport.responseText);
|
70 |
+
}
|
71 |
+
});
|
72 |
+
}
|
73 |
+
|
74 |
+
}
|
75 |
+
//]]>
|
76 |
+
</script>
|
77 |
+
|
78 |
+
HTML;
|
79 |
+
|
80 |
+
}
|
81 |
+
return $res;
|
82 |
+
}
|
83 |
+
|
84 |
+
private function _toJson($input) {
|
85 |
+
return json_encode($input);
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
89 |
+
|
app/code/community/Eabi/Livehandler/Block/Footer.php
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Footer
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_LiveHandler_Block_Footer extends Mage_Core_Block_Template {
|
34 |
+
//put your code here
|
35 |
+
|
36 |
+
|
37 |
+
protected function _toHtml() {
|
38 |
+
|
39 |
+
$resultHtml = '';
|
40 |
+
|
41 |
+
if (!$this->_getEabi()->getConfigData('eabi_livehandler/main/enabled')) {
|
42 |
+
Mage::getSingleton('core/session')->unsetData('eabi_livehandler_entries');
|
43 |
+
return $resultHtml;
|
44 |
+
}
|
45 |
+
|
46 |
+
$isAdmin = false;
|
47 |
+
$urlKey = 'eabi_livehandler/index/process';
|
48 |
+
if (Mage::app()->getStore()->isAdmin()) {
|
49 |
+
$isAdmin = true;
|
50 |
+
$urlKey = 'eabi_livehandler/adminhtml_livehandler/process';
|
51 |
+
}
|
52 |
+
$path = '';
|
53 |
+
$website = Mage::app()->getStore()->getWebsiteId();
|
54 |
+
$store = Mage::app()->getStore()->getStoreId();
|
55 |
+
$request = Mage::app()->getRequest();
|
56 |
+
|
57 |
+
Mage::getSingleton('core/session')->unsetData('eabi_livehandler_entries');
|
58 |
+
|
59 |
+
if ($isAdmin) {
|
60 |
+
if ($request->getParam('store')) {
|
61 |
+
$store = Mage::getModel('core/store')->load($request->getParam('store'))->getId();
|
62 |
+
}
|
63 |
+
if ($request->getParam('website')) {
|
64 |
+
$website = Mage::getModel('core/website')->load($request->getParam('website'))->getId();
|
65 |
+
}
|
66 |
+
|
67 |
+
}
|
68 |
+
|
69 |
+
$routeName = $request->getRequestedRouteName();
|
70 |
+
$controllerName = $request->getRequestedControllerName();
|
71 |
+
$actionName = $request->getRequestedActionName();
|
72 |
+
$path = $routeName . '/' . $controllerName . '/' . $actionName;
|
73 |
+
// $resultHtml .= $path . '/' . $website . '/' . $store;
|
74 |
+
|
75 |
+
|
76 |
+
$actionsCollection = Mage::getModel('eabi_livehandler/entry')->getCollection()->setFilter($path, $isAdmin, $website, $store);
|
77 |
+
$lastRequestVar = null;
|
78 |
+
$allowedActions = array();
|
79 |
+
foreach ($actionsCollection as $id => $action) {
|
80 |
+
$suppliedParams = array();
|
81 |
+
$action->load($action->getId());
|
82 |
+
$targetUrl = '';
|
83 |
+
$css = '';
|
84 |
+
$js = '';
|
85 |
+
$html = '';
|
86 |
+
if ($action->getData('request_var') !== $lastRequestVar || true) {
|
87 |
+
//if we do have same path and defined many actions, then only the first one in the path will be executed.
|
88 |
+
|
89 |
+
$js = trim($action->getJs());
|
90 |
+
$css = trim($action->getCss());
|
91 |
+
$html = trim($action->getHtml());
|
92 |
+
|
93 |
+
if ($action->getData('model_class') != '') {
|
94 |
+
$allowedActions[$action->getData('model_class')] = time();
|
95 |
+
}
|
96 |
+
$params['__path'] = base64_encode($action->getData('model_class'));
|
97 |
+
|
98 |
+
if ($isAdmin) {
|
99 |
+
$targetUrl = Mage::helper('adminhtml')->getUrl($urlKey, $params);
|
100 |
+
} else {
|
101 |
+
$targetUrl = $this->getUrl($urlKey, $params);
|
102 |
+
}
|
103 |
+
|
104 |
+
$lastRequestVar = $action->getData('request_var');
|
105 |
+
|
106 |
+
if ($html != '') {
|
107 |
+
$resultHtml .= $html;
|
108 |
+
}
|
109 |
+
if ($css != '') {
|
110 |
+
$resultHtml .= <<<EOT
|
111 |
+
<style type="text/css">
|
112 |
+
{$css}
|
113 |
+
</style>
|
114 |
+
EOT;
|
115 |
+
}
|
116 |
+
if ($js != '') {
|
117 |
+
$urlString = '';
|
118 |
+
if ($targetUrl != '') {
|
119 |
+
|
120 |
+
$urlString = <<<EOT
|
121 |
+
var action_url = '{$targetUrl}';
|
122 |
+
EOT;
|
123 |
+
}
|
124 |
+
$resultHtml .= <<<EOT
|
125 |
+
<script type="text/javascript">
|
126 |
+
//<![CDATA[
|
127 |
+
(function() {
|
128 |
+
{$urlString}
|
129 |
+
|
130 |
+
{$js}
|
131 |
+
})();
|
132 |
+
//]]>
|
133 |
+
</script>
|
134 |
+
EOT;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
//execute each action and supply parameters
|
139 |
+
|
140 |
+
//execute makes the following
|
141 |
+
/*
|
142 |
+
* echo the target URL for the proper action handler
|
143 |
+
* echo action handlers CSS
|
144 |
+
* echo action handlers JS
|
145 |
+
* echo action handler HTML
|
146 |
+
*
|
147 |
+
* action url would have to execute the correct action
|
148 |
+
*
|
149 |
+
*
|
150 |
+
*
|
151 |
+
*/
|
152 |
+
}
|
153 |
+
Mage::getSingleton('core/session')->setData('eabi_livehandler_entries', $allowedActions);
|
154 |
+
return $resultHtml;
|
155 |
+
}
|
156 |
+
|
157 |
+
|
158 |
+
/**
|
159 |
+
*
|
160 |
+
* @return Eabi_Livehandler_Helper_Data
|
161 |
+
*/
|
162 |
+
protected function _getEabi() {
|
163 |
+
return Mage::helper('eabi');
|
164 |
+
}
|
165 |
+
}
|
166 |
+
|
app/code/community/Eabi/Livehandler/CHANGELOG.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
0.1.1
|
2 |
+
- Initial release
|
3 |
+
|
app/code/community/Eabi/Livehandler/Helper/Data.php
ADDED
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* <p>Handles saving and loading Magento's core_config_data values.</p>
|
30 |
+
* <p>Can save and load PHP objects to core_config_data table.</p>
|
31 |
+
*
|
32 |
+
* @author Aktsiamaailm OÜ, Matis Halmann
|
33 |
+
*/
|
34 |
+
class Eabi_Livehandler_Helper_Data extends Mage_Core_Helper_Abstract {
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* <p>Behaves similar to Mage::getStoreConfig() method, but returns PHP objects instead of strings</p>
|
39 |
+
* @param string $key configuration key to fetch
|
40 |
+
* @param string|bool $default default value to return if the value does not exist or unserialization failed
|
41 |
+
* @param int $storeId store id, to fetch the configuration value for
|
42 |
+
* @return object|array|string
|
43 |
+
*/
|
44 |
+
final public function getBigConfigData($key, $default = false, $storeId = null) {
|
45 |
+
$i = 0;
|
46 |
+
|
47 |
+
$selfValue = $this->getConfigData($key, $default, $storeId);
|
48 |
+
while (strlen($loadedString = $this->getConfigData($key . $i, $default, $storeId)) > 0) {
|
49 |
+
if (!is_string($loadedString)) {
|
50 |
+
break;
|
51 |
+
}
|
52 |
+
$selfValue .= $loadedString;
|
53 |
+
$i++;
|
54 |
+
}
|
55 |
+
|
56 |
+
$finalValue = @unserialize(@gzuncompress(@base64_decode($selfValue)));
|
57 |
+
|
58 |
+
if (!is_array($finalValue)) {
|
59 |
+
return $default;
|
60 |
+
}
|
61 |
+
return $finalValue;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* <p>Stores PHP object to core_config_data table using object serialization.</p>
|
66 |
+
* <p>Save procedure of stored object:
|
67 |
+
* <ul>
|
68 |
+
<li>serialize php object</li>
|
69 |
+
<li>gzcompress the serialized result</li>
|
70 |
+
<li>base64 encode the compressed result</li>
|
71 |
+
<li>If the compressed result is larger than 64K, then the resulting blocks will be saved under $key . $i ID, where $i starts with 0 and is incremented by 1 for each consecutive 64K block.</li>
|
72 |
+
</ul>
|
73 |
+
* </p>
|
74 |
+
* @param string $key configuration key to store this value
|
75 |
+
* @param object|array|string $value object to store into the configuration
|
76 |
+
* @param string $scope Magento's configuration scope
|
77 |
+
* @param int $scopeId store ID this configuration will be saved to
|
78 |
+
* @param bool $skipFirst if this setting is true, then first segment will not be saved to database using this function. Useful, when overriding Mage_Core_Model_Config_Data saving functions.
|
79 |
+
* @return string first saved segment of this saved configuration data.
|
80 |
+
*/
|
81 |
+
final public function setBigConfigData($key, $value, $scope = 'default', $scopeId = 0, $skipFirst = false) {
|
82 |
+
$strValue = base64_encode(gzcompress(serialize($value)));
|
83 |
+
$strValues = str_split($strValue, 64000);
|
84 |
+
$cnt = 0;
|
85 |
+
|
86 |
+
$firstValue = array_shift($strValues);
|
87 |
+
if (!$skipFirst) {
|
88 |
+
$this->setConfigData($key, $firstValue, $scope, $scopeId, false);
|
89 |
+
}
|
90 |
+
|
91 |
+
foreach ($strValues as $strVal) {
|
92 |
+
$this->setConfigData($key . $cnt, $strVal, $scope, $scopeId, false);
|
93 |
+
$cnt ++;
|
94 |
+
}
|
95 |
+
$this->setConfigData($key . $cnt, '', $scope, $scopeId, true);
|
96 |
+
return $firstValue;
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* <p>Behaves similar to Mage::getStoreConfig() but attempts to return the resulting value as float.</p>
|
102 |
+
* <p>Supports "." and "," as decimal separator</p>
|
103 |
+
* @param string $key configuration key to load
|
104 |
+
* @param bool|object $default default value to return if the configuration value does not exist.
|
105 |
+
* @param int $storeId store id to load the configuration value for.
|
106 |
+
* @return float
|
107 |
+
*/
|
108 |
+
final public function getConfigDataF($key, $default = false, $storeId = null) {
|
109 |
+
return $this->getConfigData($key, $default, $storeId, true);
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* <p>Behaves similar to Mage::getStoreConfig() but returns array of elements, where each element is one line of data contained. Empty lines are not returned.</p>
|
114 |
+
* @param string $key configuration key to load
|
115 |
+
* @param bool|object $default default value to return if the configuration value does not exist.
|
116 |
+
* @param int $storeId store id to load the configuration value for.
|
117 |
+
* @return array
|
118 |
+
*/
|
119 |
+
final public function getConfigDataA($key, $default = false, $storeId = null) {
|
120 |
+
$value = $this->getConfigData($key, $default, $storeId, false);
|
121 |
+
if (is_string($value)) {
|
122 |
+
$rawModules = explode("\n", $value);
|
123 |
+
return array_filter(array_map('trim', $rawModules));
|
124 |
+
}
|
125 |
+
return $value;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* <p>Behaves similar to Mage::getStoreConfig() function and can return the value as float.</p>
|
130 |
+
* @param string $key configuration key to load
|
131 |
+
* @param bool|object $default default value to return if the configuration value does not exist.
|
132 |
+
* @param int $storeId store id to load the configuration value for.
|
133 |
+
* @param bool $asFloat when true, then attemts to return the value as float
|
134 |
+
* @return string
|
135 |
+
*/
|
136 |
+
final public function getConfigData($key, $default = false, $storeId = null, $asFloat = false) {
|
137 |
+
if ($storeId === null) {
|
138 |
+
$storeId = Mage::app()->getStore()->getId();
|
139 |
+
}
|
140 |
+
$value = Mage::getStoreConfig($key, $storeId);
|
141 |
+
if (is_null($value) || false === $value) {
|
142 |
+
$value = $default;
|
143 |
+
}
|
144 |
+
if ($asFloat) {
|
145 |
+
$value = str_replace(',', '.', $value);
|
146 |
+
}
|
147 |
+
return $value;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* <p>Writes the core_config_data value to database and resets the cache.</p>
|
152 |
+
* @param string $key Identification path to write the configuarion to.
|
153 |
+
* @param string $value Value to store
|
154 |
+
* @param string $scope Magento's scope to apply
|
155 |
+
* @param int $scopeId Store ID to apply
|
156 |
+
* @param bool $resetCache If the cache should be reset after saving the configuration value.
|
157 |
+
* @return Eabi_Livehandler_Helper_Data
|
158 |
+
*/
|
159 |
+
final public function setConfigData($key, $value, $scope = 'default', $scopeId = 0, $resetCache = true) {
|
160 |
+
$config = Mage::getConfig();
|
161 |
+
$config->saveConfig($key, $value, $scope, $scopeId);
|
162 |
+
if ($resetCache) {
|
163 |
+
$config->cleanCache();
|
164 |
+
}
|
165 |
+
return $this;
|
166 |
+
}
|
167 |
+
|
168 |
+
|
169 |
+
|
170 |
+
}
|
171 |
+
|
172 |
+
|
app/code/community/Eabi/Livehandler/LICENCE.txt
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
http://opensource.org/licenses/osl-3.0.php
|
app/code/community/Eabi/Livehandler/Model/Abstract.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Abstract
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
abstract class Eabi_Livehandler_Model_Abstract extends Mage_Core_Model_Abstract {
|
34 |
+
//put your code here
|
35 |
+
|
36 |
+
//construct will be done in subclasses
|
37 |
+
|
38 |
+
public function getJs() {
|
39 |
+
return '';
|
40 |
+
}
|
41 |
+
|
42 |
+
public function getCss() {
|
43 |
+
return '';
|
44 |
+
}
|
45 |
+
|
46 |
+
public function getHtml() {
|
47 |
+
return '';
|
48 |
+
}
|
49 |
+
|
50 |
+
public function process($postedData) {
|
51 |
+
return array();
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
55 |
+
?>
|
app/code/community/Eabi/Livehandler/Model/Action/Abstract.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Abstract
|
30 |
+
*
|
31 |
+
* @author Matis
|
32 |
+
*/
|
33 |
+
abstract class Eabi_Livehandler_Model_Action_Abstract {
|
34 |
+
protected $_position;
|
35 |
+
protected $_code;
|
36 |
+
protected $_label;
|
37 |
+
protected $_onClick;
|
38 |
+
protected $_longOnClick;
|
39 |
+
protected $_cssClass;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Decides whether the button can be displayed for the current order
|
43 |
+
*/
|
44 |
+
abstract public function canDisplay(Mage_Sales_Model_Order $order);
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Performs the desired action, when button can be displayed and the button itself is clicked
|
48 |
+
* Should return:
|
49 |
+
* - messages
|
50 |
+
* - errors
|
51 |
+
* - any other data
|
52 |
+
*
|
53 |
+
*/
|
54 |
+
abstract public function performDesiredAction(Mage_Sales_Model_Order $order, array $params);
|
55 |
+
|
56 |
+
|
57 |
+
public function setPosition($position) {
|
58 |
+
$this->_position = $position;
|
59 |
+
}
|
60 |
+
public function getPosition() {
|
61 |
+
return $this->_position;
|
62 |
+
}
|
63 |
+
|
64 |
+
public function getCode() {
|
65 |
+
return $this->_code;
|
66 |
+
}
|
67 |
+
|
68 |
+
public function getLabel() {
|
69 |
+
return $this->_label;
|
70 |
+
}
|
71 |
+
|
72 |
+
public function getOnClick() {
|
73 |
+
return $this->_onClick;
|
74 |
+
}
|
75 |
+
public function getCssClass() {
|
76 |
+
return $this->_cssClass;
|
77 |
+
}
|
78 |
+
public function getLongOnClick() {
|
79 |
+
return $this->_longOnClick;
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
protected function _toJson($input) {
|
84 |
+
return json_encode($input);
|
85 |
+
}
|
86 |
+
|
87 |
+
}
|
88 |
+
|
app/code/community/Eabi/Livehandler/Model/Adminhtml/Gridmanager.php
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Gridmanager
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Model_Adminhtml_Gridmanager extends Eabi_Livehandler_Model_Abstract {
|
34 |
+
|
35 |
+
protected $_actionButtons = array();
|
36 |
+
//put your code here
|
37 |
+
public function _construct() {
|
38 |
+
parent::_construct();
|
39 |
+
$this->_init('eabi_livehandler/adminhtml_gridmanager');
|
40 |
+
}
|
41 |
+
|
42 |
+
public function addActionButton($id, $title, $onclick) {
|
43 |
+
$this->_actionButtons[$id] = array(
|
44 |
+
'title' => $title,
|
45 |
+
'onclick' => $onclick,
|
46 |
+
);
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
|
50 |
+
public function removeActionButton($id) {
|
51 |
+
if (isset($this->_actionButtons[$id])) {
|
52 |
+
unset($this->_actionButtons[$id]);
|
53 |
+
}
|
54 |
+
return $this;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Encodes input to JSON
|
59 |
+
* @param mixed $input
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
protected function _encode($input) {
|
63 |
+
return json_encode($input);
|
64 |
+
|
65 |
+
}
|
66 |
+
|
67 |
+
public function getJs() {
|
68 |
+
$js = '';
|
69 |
+
|
70 |
+
foreach ($this->_actionButtons as $id => $actionButton) {
|
71 |
+
$onclick = str_replace('\"','"',addslashes($actionButton['onclick']));
|
72 |
+
$title = str_replace('\"','"',addslashes($actionButton['title']));
|
73 |
+
$js .= <<<EOT
|
74 |
+
var button_{$id} = new Element('button');
|
75 |
+
button_{$id}.writeAttribute('id', '{$id}');
|
76 |
+
button_{$id}.writeAttribute('type', 'button');
|
77 |
+
button_{$id}.writeAttribute('class', 'scalable');
|
78 |
+
button_{$id}.writeAttribute('onclick', '{$onclick}');
|
79 |
+
button_{$id}.update('<span>{$title}</span>');
|
80 |
+
|
81 |
+
$$('p.form-buttons').first().insert(button_{$id}, { position: 'bottom'});
|
82 |
+
|
83 |
+
EOT;
|
84 |
+
}
|
85 |
+
|
86 |
+
$js .= $this->_getAdditionalJs($js);
|
87 |
+
|
88 |
+
return $js;
|
89 |
+
}
|
90 |
+
|
91 |
+
protected function _getAdditionalJs($currentJs) {
|
92 |
+
return '';
|
93 |
+
}
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
public function service($postData) {
|
98 |
+
return array();
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
app/code/community/Eabi/Livehandler/Model/Entry.php
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Entry
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Model_Entry extends Mage_Core_Model_Abstract {
|
34 |
+
|
35 |
+
/**
|
36 |
+
*
|
37 |
+
* @var Eabi_Livehandler_Model_Adminhtml_Gridmanager
|
38 |
+
*/
|
39 |
+
private $_caller;
|
40 |
+
|
41 |
+
public function _construct() {
|
42 |
+
parent::_construct();
|
43 |
+
$this->_init('eabi_livehandler/entry');
|
44 |
+
|
45 |
+
}
|
46 |
+
|
47 |
+
protected function _afterLoad() {
|
48 |
+
$load = parent::_afterLoad();
|
49 |
+
if ($this->getData('model_class') != '') {
|
50 |
+
$this->_caller = Mage::getModel($this->getData('model_class'));
|
51 |
+
}
|
52 |
+
return $load;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function getJs() {
|
56 |
+
$js = trim($this->getData('js'));
|
57 |
+
if ($js == '' && $this->_caller != null) {
|
58 |
+
$js = $this->_caller->getJs();
|
59 |
+
}
|
60 |
+
|
61 |
+
return $js;
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
public function getCss() {
|
66 |
+
$css = trim($this->getData('css'));
|
67 |
+
if ($css == '' && $this->_caller != null) {
|
68 |
+
$css = $this->_caller->getCss();
|
69 |
+
}
|
70 |
+
|
71 |
+
return $css;
|
72 |
+
|
73 |
+
}
|
74 |
+
|
75 |
+
public function getHtml() {
|
76 |
+
$html = trim($this->getData('html'));
|
77 |
+
if ($html == '' && $this->_caller != null) {
|
78 |
+
$html = $this->_caller->getHtml();
|
79 |
+
}
|
80 |
+
|
81 |
+
return $html;
|
82 |
+
|
83 |
+
}
|
84 |
+
|
85 |
+
public function runPublic($postedData) {
|
86 |
+
$result = array();
|
87 |
+
if ($this->_caller != null) {
|
88 |
+
$result = $this->_caller->service($postedData);
|
89 |
+
}
|
90 |
+
return $result;
|
91 |
+
}
|
92 |
+
public function runAdmin($postedData) {
|
93 |
+
$result = array();
|
94 |
+
if ($this->_caller != null) {
|
95 |
+
$result = $this->_caller->service($postedData);
|
96 |
+
}
|
97 |
+
return $result;
|
98 |
+
}
|
99 |
+
}
|
app/code/community/Eabi/Livehandler/Model/Mysql4/Entry.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Entry
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Model_Mysql4_Entry extends Mage_Core_Model_Mysql4_Abstract {
|
34 |
+
//put your code here
|
35 |
+
|
36 |
+
public function _construct() {
|
37 |
+
$this->_init('eabi_livehandler/entry', 'id');
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
|
app/code/community/Eabi/Livehandler/Model/Mysql4/Entry/Collection.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Collection
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Model_Mysql4_Entry_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
|
34 |
+
//put your code here
|
35 |
+
public function _construct() {
|
36 |
+
parent::_construct();
|
37 |
+
$this->_init('eabi_livehandler/entry');
|
38 |
+
}
|
39 |
+
|
40 |
+
public function setFilter($path, $isAdmin = false, $website = 0, $store = 0) {
|
41 |
+
$this->addFieldToFilter('request_var', array('like' => $path.'%'));
|
42 |
+
$this->addFieldToFilter('is_admin', (int)$isAdmin);
|
43 |
+
$this->addFieldToFilter('is_enabled', 1);
|
44 |
+
$this->getSelect()->where('main_table.website_id = '.((int)$website).' or main_table.website_id = 0');
|
45 |
+
$this->getSelect()->where('main_table.store_id = '.((int)$store).' or main_table.store_id = 0');
|
46 |
+
$this->addOrder('request_var', 'asc');
|
47 |
+
$this->addOrder('website_id', 'desc');
|
48 |
+
$this->addOrder('store_id', 'desc');
|
49 |
+
return $this;
|
50 |
+
}
|
51 |
+
public function setModelFilter($model, $isAdmin = false, $website = 0, $store = 0) {
|
52 |
+
$this->addFieldToFilter('model_class', $model);
|
53 |
+
$this->addFieldToFilter('is_admin', (int)$isAdmin);
|
54 |
+
$this->addFieldToFilter('is_enabled', 1);
|
55 |
+
$this->getSelect()->where('main_table.website_id = '.((int)$website).' or main_table.website_id = 0');
|
56 |
+
$this->getSelect()->where('main_table.store_id = '.((int)$store).' or main_table.store_id = 0');
|
57 |
+
$this->addOrder('request_var', 'asc');
|
58 |
+
$this->addOrder('website_id', 'desc');
|
59 |
+
$this->addOrder('store_id', 'desc');
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
}
|
63 |
+
?>
|
app/code/community/Eabi/Livehandler/Model/Ordergrid.php
ADDED
@@ -0,0 +1,814 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Ordergrid
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Model_Ordergrid extends Eabi_Livehandler_Model_Adminhtml_Gridmanager {
|
34 |
+
|
35 |
+
private static $_allowedActions;
|
36 |
+
private static $_hasButtons = false;
|
37 |
+
CONST CACHE_KEY = 'eabi_livehandler_model_ordergrid';
|
38 |
+
|
39 |
+
protected $_loadedButtons = array();
|
40 |
+
|
41 |
+
|
42 |
+
public function _construct() {
|
43 |
+
parent::_construct();
|
44 |
+
$this->_init('eabi_livehandler/ordergrid');
|
45 |
+
$this->_initButtons();
|
46 |
+
}
|
47 |
+
|
48 |
+
private function _initButtons() {
|
49 |
+
if (self::$_allowedActions === null) {
|
50 |
+
//first check the folder model/actions if the checked result is not already stored in cache
|
51 |
+
//effectively each time cache is cleared existense for new button classes is checked
|
52 |
+
//if cache is disabled entirely then each load time existense of the button classes is checked when
|
53 |
+
//order detail view screen is loaded
|
54 |
+
$cache = Mage::app()->getCache();
|
55 |
+
/* @var $cache Mage_Core_Model_Cache */
|
56 |
+
$configStored = $cache->load(self::CACHE_KEY);
|
57 |
+
if ($configStored != 'true') {
|
58 |
+
//reload the config
|
59 |
+
/* @var $configBackend Eabi_Livehandler_Model_System_Config_Backend_Button */
|
60 |
+
$configBackend = Mage::getModel('eabi_livehandler/system_config_backend_button');
|
61 |
+
$configBackend->load('eabi_livehandler/admintools/buttons', 'path');
|
62 |
+
$configBackend->save();
|
63 |
+
if ($configBackend->isValueChanged() && is_array($configBackend->getValue())) {
|
64 |
+
$this->getEabi()->setConfigData('eabi_livehandler/admintools/buttons', serialize($configBackend->getValue()));
|
65 |
+
}
|
66 |
+
|
67 |
+
//since the actual configuration is saved in core_config_data, which is cached anyway
|
68 |
+
//then we only need a mark that we checked for the existence
|
69 |
+
//put lifetime=forever, because new check should be performed only when cache is cleared
|
70 |
+
//cache tag should be configuration, because we hold the actual value in Magentos configuration
|
71 |
+
$cache->save('true', self::CACHE_KEY, array(Mage_Core_Model_Config::CACHE_TAG), 0);
|
72 |
+
|
73 |
+
}
|
74 |
+
|
75 |
+
//read the available button classes from the configuration
|
76 |
+
//because detecting the buttons from the folder is slow, that is why only configuration is checked.
|
77 |
+
$allowedActions = @unserialize(Mage::getStoreConfig('eabi_livehandler/admintools/buttons'));
|
78 |
+
if (!is_array($allowedActions)) {
|
79 |
+
//we have no buttons, or the saved configuration was garbage
|
80 |
+
$allowedActions = array();
|
81 |
+
}
|
82 |
+
self::$_allowedActions = array();
|
83 |
+
//sort the allowed actions by sort_order
|
84 |
+
uasort($allowedActions, array(__CLASS__, '_sortAction'));
|
85 |
+
foreach ($allowedActions as $allowedAction) {
|
86 |
+
//exclude disabled button classes
|
87 |
+
if (!(bool)$allowedAction['disabled']) {
|
88 |
+
self::$_allowedActions[] = $allowedAction['button_name'];
|
89 |
+
}
|
90 |
+
self::$_hasButtons = true;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
|
96 |
+
public static function _sortAction($a, $b) {
|
97 |
+
if ((bool)$a['disabled'] && !(bool)$b['disabled']) {
|
98 |
+
return 1;
|
99 |
+
}
|
100 |
+
if (!(bool)$a['disabled'] && (bool)$b['disabled']) {
|
101 |
+
return -1;
|
102 |
+
}
|
103 |
+
if ((int)$a['sort_order'] == (int)$b['sort_order']) {
|
104 |
+
return 0;
|
105 |
+
}
|
106 |
+
return (int)$a['sort_order'] < (int)$b['sort_order']?-1:1;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Returns result for the ajax call for this action.
|
111 |
+
* Parameters it the postdata itself.
|
112 |
+
* If this module is disabled, then assoc array of
|
113 |
+
* array('result' => false); is returned.
|
114 |
+
*
|
115 |
+
* @param array $postData
|
116 |
+
* @return array
|
117 |
+
*/
|
118 |
+
public function service($postData) {
|
119 |
+
$errors = array();
|
120 |
+
$messages = array();
|
121 |
+
|
122 |
+
$result = array(
|
123 |
+
'success' => false,
|
124 |
+
'set_location' => false,
|
125 |
+
);
|
126 |
+
if (!Mage::getStoreConfig('eabi_livehandler/admintools/enabled')) {
|
127 |
+
return $result;
|
128 |
+
}
|
129 |
+
if (isset($postData['order_id'])) {
|
130 |
+
$order = Mage::getModel('sales/order')->load($postData['order_id']);
|
131 |
+
if ($order->getId() > 0) {
|
132 |
+
$isActionError = false;
|
133 |
+
|
134 |
+
|
135 |
+
//send_email
|
136 |
+
//unhold
|
137 |
+
//hold
|
138 |
+
//cancel
|
139 |
+
//invoice
|
140 |
+
if (isset($postData['action']) && in_array($postData['action'], self::$_allowedActions)) {
|
141 |
+
$actionModel = Mage::getSingleton('eabi_livehandler/action_'.$postData['action']);
|
142 |
+
/* @var $actionModel Eabi_Livehandler_Model_Action_Abstract */
|
143 |
+
if ($actionModel && $actionModel instanceof Eabi_Livehandler_Model_Action_Abstract
|
144 |
+
&& $actionModel->canDisplay($order)) {
|
145 |
+
$data = isset($postData['extra_data'])?json_decode($postData['extra_data'], true):array();
|
146 |
+
if (!is_array($data)) {
|
147 |
+
$data = array();
|
148 |
+
}
|
149 |
+
$actionResult = $actionModel->performDesiredAction($order, $data);
|
150 |
+
if (isset($actionResult['errors'])) {
|
151 |
+
$errors = array_merge($messages, $actionResult['errors']);
|
152 |
+
}
|
153 |
+
$messages = array_merge($messages, $actionResult['messages']);
|
154 |
+
$isActionError = $actionResult['is_action_error'];
|
155 |
+
$result['needs_reload'] = $actionResult['needs_reload'];
|
156 |
+
if (isset($actionResult['set_location'])) {
|
157 |
+
$result['set_location'] = $actionResult['set_location'];
|
158 |
+
}
|
159 |
+
} else {
|
160 |
+
$isActionError = true;
|
161 |
+
}
|
162 |
+
} else {
|
163 |
+
// $isActionError = true;
|
164 |
+
}
|
165 |
+
if ($isActionError) {
|
166 |
+
$errors[] = Mage::helper('eabi_livehandler')->__('Invalid action');
|
167 |
+
$result['needs_reload'] = true;
|
168 |
+
}
|
169 |
+
if ($result['set_location'] && strlen($result['set_location'])> 3) {
|
170 |
+
return $result;
|
171 |
+
}
|
172 |
+
|
173 |
+
$address = $order->getShippingAddress();
|
174 |
+
if (!$address) {
|
175 |
+
$address = $order->getBillingAddress();
|
176 |
+
}
|
177 |
+
|
178 |
+
$result['_order'] = $order->debug();
|
179 |
+
$result['address'] = $address->format('html');
|
180 |
+
$result['customer_email'] = htmlspecialchars($order->getCustomerEmail());
|
181 |
+
$result['total_paid'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseTotalPaid(), true, false));
|
182 |
+
$result['grand_total'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseGrandTotal(), true, false));
|
183 |
+
$result['base_shipping'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseShippingAmount(), true, false));
|
184 |
+
$result['base_total'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseGrandTotal() - $order->getBaseShippingAmount(), true, false));
|
185 |
+
$result['base_subtotal_to_refund'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseSubtotalInvoiced() - $order->getBaseSubtotalRefunded(), true, false));
|
186 |
+
$result['base_total_to_refund'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseTotalInvoiced() - $order->getBaseTotalRefunded(), true, false));
|
187 |
+
$result['payment'] = htmlspecialchars($order->getPayment()->getMethodInstance()->getTitle());
|
188 |
+
$result['shipping'] = htmlspecialchars($order->getShippingDescription());
|
189 |
+
if ($result['shipping'] == '') {
|
190 |
+
$result['shipping'] = Mage::helper('eabi_livehandler')->__('Not applicable');
|
191 |
+
}
|
192 |
+
$result['status_label'] = htmlspecialchars($order->getStatusLabel());
|
193 |
+
$result['discount_description'] = htmlspecialchars($order->getDiscountDescription());
|
194 |
+
if ($order->getBaseDiscountAmount() > 0) {
|
195 |
+
$result['discount_amount'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseDiscountAmount() * -1, true, false));
|
196 |
+
|
197 |
+
} else {
|
198 |
+
$result['discount_amount'] = htmlspecialchars(Mage::helper('core')->currency($order->getBaseDiscountAmount(), true, false));
|
199 |
+
|
200 |
+
}
|
201 |
+
$orderItems = $order->getAllVisibleItems();
|
202 |
+
$products = array();
|
203 |
+
foreach ($orderItems as $orderItem) {
|
204 |
+
|
205 |
+
// $products[] = $orderItem->debug() + array('prod_options' => $orderItem->getProductOptions());
|
206 |
+
|
207 |
+
$html = <<<EOT
|
208 |
+
<tr>
|
209 |
+
<td class="a-left">%name%</td>
|
210 |
+
<td>%sku%</td>
|
211 |
+
<td>%qty%</td>
|
212 |
+
<td>%price%</td>
|
213 |
+
<td>%total%</td>
|
214 |
+
</tr>
|
215 |
+
|
216 |
+
EOT;
|
217 |
+
$name = htmlspecialchars($orderItem->getName());
|
218 |
+
$options = $orderItem->getProductOptions();
|
219 |
+
$option = '';
|
220 |
+
if (isset($options['options'])) {
|
221 |
+
foreach ($options['options'] as $optionValues) {
|
222 |
+
if ($optionValues['value']) {
|
223 |
+
$option .= '<br/><strong><i>'. htmlspecialchars($optionValues['label']).'</i></strong>: ';
|
224 |
+
$_printValue = isset($optionValues['print_value']) ? $optionValues['print_value'] : strip_tags($optionValues['value']);
|
225 |
+
$values = explode(', ', $_printValue);
|
226 |
+
foreach ($values as $value) {
|
227 |
+
if (is_array($value)) {
|
228 |
+
foreach ($value as $_value) {
|
229 |
+
$option .= htmlspecialchars($_value);
|
230 |
+
}
|
231 |
+
} else {
|
232 |
+
$option .= htmlspecialchars($value);
|
233 |
+
}
|
234 |
+
$option .= '<br/>';
|
235 |
+
}
|
236 |
+
}
|
237 |
+
}
|
238 |
+
}
|
239 |
+
$name .= $option;
|
240 |
+
$basePrice = $orderItem->getBasePriceInclTax();
|
241 |
+
if ($basePrice == null) {
|
242 |
+
$basePrice = $orderItem->getBasePrice();
|
243 |
+
}
|
244 |
+
$toReplace = array(
|
245 |
+
'name' => $name,
|
246 |
+
'sku' => htmlspecialchars($orderItem->getSku()),
|
247 |
+
'qty' => round($orderItem->getQtyOrdered()),
|
248 |
+
'price' => Mage::helper('core')->currency($basePrice, true, false),
|
249 |
+
'total' => Mage::helper('core')->currency($basePrice * $orderItem->getQtyOrdered(), true, false),
|
250 |
+
);
|
251 |
+
|
252 |
+
foreach ($toReplace as $key => $value) {
|
253 |
+
$html = str_replace('%'.$key.'%', $value, $html);
|
254 |
+
}
|
255 |
+
|
256 |
+
$products[] = array(
|
257 |
+
'name' => $orderItem->getName(),
|
258 |
+
'base_original_price' => $orderItem->getBaseOriginalPrice(),
|
259 |
+
'base_price' => $orderItem->getBasePrice(),
|
260 |
+
'base_price_incl_tax' => $orderItem->getBasePriceInclTax(),
|
261 |
+
'original_price' => $orderItem->getOriginalPrice(),
|
262 |
+
'price' => $orderItem->getPrice(),
|
263 |
+
'price_incl_tax' => $orderItem->getPriceInclTax(),
|
264 |
+
'product_id' => $orderItem->getProductId(),
|
265 |
+
'product_options' => $orderItem->getProductOptions(),
|
266 |
+
'qty_ordered' => $orderItem->getQtyOrdered(),
|
267 |
+
'row_total' => $orderItem->getRowTotal(),
|
268 |
+
'row_total_incl_tax' => $orderItem->getRowTotalInclTax(),
|
269 |
+
'sku' => $orderItem->getSku(),
|
270 |
+
'tax_amount' => $orderItem->getTaxAmount(),
|
271 |
+
'tax_percent' => $orderItem->getTaxPercent(),
|
272 |
+
'html' => $html,
|
273 |
+
);
|
274 |
+
|
275 |
+
}
|
276 |
+
|
277 |
+
$buttonsHtml = '';
|
278 |
+
if (!self::$_hasButtons) {
|
279 |
+
$buttonsHtml .= '<span class="eabi_commercial">'.$this->getEabi()->__('Manage the order from here by adding <a href=\'%s\' target=\'_blank\'>action buttons</a>', $this->getEabi()->__($this->getEabi()->getConfigData('eabi_livehandler/admintools/buttons_url'))).'</span>';
|
280 |
+
}
|
281 |
+
|
282 |
+
foreach (self::$_allowedActions as $allowedAction) {
|
283 |
+
$actionButtonModel = Mage::getSingleton('eabi_livehandler/action_'.$allowedAction);
|
284 |
+
/* @var $actionButtonModel Eabi_Livehandler_Model_Action_Abstract */
|
285 |
+
if ($actionButtonModel && $actionButtonModel instanceof Eabi_Livehandler_Model_Action_Abstract
|
286 |
+
&& $actionButtonModel->canDisplay($order)) {
|
287 |
+
$buttonsHtml .= $this->__makeActionButton($actionButtonModel->getLabel(), $actionButtonModel->getOnClick(), $actionButtonModel->getCssClass(), 'eabi_'.$actionButtonModel->getCode());
|
288 |
+
$this->_loadedButtons = $actionButtonModel;
|
289 |
+
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
|
294 |
+
/* @var $adminHelper Mage_Adminhtml_Helper_Data */
|
295 |
+
$adminHelper = Mage::helper('adminhtml');
|
296 |
+
$result['success'] = true;
|
297 |
+
$result['header_html'] = <<<EOT
|
298 |
+
<div class="grid products_grid">
|
299 |
+
<table><thead>
|
300 |
+
<tr class="headings">
|
301 |
+
<th>{$adminHelper->__('Product')}</th>
|
302 |
+
<th>{$adminHelper->__('SKU')}</th>
|
303 |
+
<th>{$adminHelper->__('Qty')}</th>
|
304 |
+
<th>{$adminHelper->__('Price')}</th>
|
305 |
+
<th>{$adminHelper->__('Row Total')}</th>
|
306 |
+
</tr>
|
307 |
+
</thead>
|
308 |
+
<tbody>
|
309 |
+
EOT;
|
310 |
+
$result['footer_html'] = <<<EOT
|
311 |
+
</tbody>
|
312 |
+
</table>
|
313 |
+
</div>
|
314 |
+
EOT;
|
315 |
+
|
316 |
+
$result['customer_address_html'] = '';
|
317 |
+
|
318 |
+
if (count($errors) > 0 || count($messages) > 0) {
|
319 |
+
$result['customer_address_html'] .= '<ul class="messages">';
|
320 |
+
|
321 |
+
if (count($messages) > 0) {
|
322 |
+
$result['customer_address_html'] .= '<li class="success-msg"><ul>';
|
323 |
+
foreach ($messages as $message) {
|
324 |
+
$result['customer_address_html'] .= '<li>'. htmlspecialchars($message).'</li>';
|
325 |
+
}
|
326 |
+
$result['customer_address_html'] .= '</ul></li>';
|
327 |
+
}
|
328 |
+
|
329 |
+
if (count($errors) > 0) {
|
330 |
+
$result['customer_address_html'] .= '<li class="error-msg"><ul>';
|
331 |
+
foreach ($errors as $error) {
|
332 |
+
$result['customer_address_html'] .= '<li>'. htmlspecialchars($error).'</li>';
|
333 |
+
}
|
334 |
+
$result['customer_address_html'] .= '</ul></li>';
|
335 |
+
}
|
336 |
+
|
337 |
+
$result['customer_address_html'] .= '</ul>';
|
338 |
+
}
|
339 |
+
$_blank = '';
|
340 |
+
if (Mage::getStoreConfig('eabi_livehandler/admintools/open_in_new')) {
|
341 |
+
$_blank = ' target="_blank"';
|
342 |
+
}
|
343 |
+
$orderUrl = Mage::helper('adminhtml')->getUrl('adminhtml/sales_order/view', array('order_id' => $order->getId()));
|
344 |
+
$result['customer_address_html'] .= <<<EOT
|
345 |
+
<div class="grid detail_grid">
|
346 |
+
<table><thead>
|
347 |
+
<tr class="headings">
|
348 |
+
<th>{$result['total_paid']}/{$result['grand_total']}</th>
|
349 |
+
<th class="a-right"><div class="eabi_buttons">{$buttonsHtml}</div> <a href="{$orderUrl}" title="{$adminHelper->__('View')}" {$_blank}>{$result['status_label']}</a></strong></th>
|
350 |
+
</tr>
|
351 |
+
</thead>
|
352 |
+
<tbody>
|
353 |
+
<tr>
|
354 |
+
<td class="a-left"><strong><a href="mailto:{$result['customer_email']}">{$result['customer_email']}</a></strong><br/>{$result['address']}</td>
|
355 |
+
<td>
|
356 |
+
<table>
|
357 |
+
<thead>
|
358 |
+
<tr>
|
359 |
+
<th>{$adminHelper->__('Payment Information')}</th>
|
360 |
+
</tr>
|
361 |
+
</thead>
|
362 |
+
<tbody>
|
363 |
+
<tr>
|
364 |
+
<td>{$result['payment']}</td>
|
365 |
+
</tr>
|
366 |
+
</tbody>
|
367 |
+
</table>
|
368 |
+
<table>
|
369 |
+
<thead>
|
370 |
+
<tr>
|
371 |
+
<th>{$adminHelper->__('Shipping & Handling Information')}</th>
|
372 |
+
</tr>
|
373 |
+
</thead>
|
374 |
+
<tbody>
|
375 |
+
<tr>
|
376 |
+
<td>{$result['shipping']}</td>
|
377 |
+
</tr>
|
378 |
+
</tbody>
|
379 |
+
</table>
|
380 |
+
</td>
|
381 |
+
</tr>
|
382 |
+
</tbody>
|
383 |
+
</table>
|
384 |
+
</div>
|
385 |
+
|
386 |
+
EOT;
|
387 |
+
|
388 |
+
if ($order->getBaseDiscountAmount() < 0 || $order->getBaseDiscountAmount() > 0) {
|
389 |
+
if ($result['discount_description'] == '') {
|
390 |
+
$result['discount_description'] = $order->getCouponCode();
|
391 |
+
}
|
392 |
+
$result['footer_html'] .= <<<EOT
|
393 |
+
<div class="grid discounts_grid">
|
394 |
+
<table><thead>
|
395 |
+
<tr class="headings">
|
396 |
+
<th>{$adminHelper->__('Discount')}: {$result['discount_description']}</th>
|
397 |
+
<th class="a-right"><strong>{$result['discount_amount']}</strong></th>
|
398 |
+
</tr>
|
399 |
+
</thead>
|
400 |
+
<tbody>
|
401 |
+
</tbody>
|
402 |
+
</table>
|
403 |
+
</div>
|
404 |
+
|
405 |
+
EOT;
|
406 |
+
}
|
407 |
+
$date = $order->getCreatedAtFormated('medium');
|
408 |
+
$result['title_html'] = htmlspecialchars(sprintf(Mage::helper('sales')->__('Order #%s - %s'), $order->getIncrementId(), $date));
|
409 |
+
$result['products'] = $products;
|
410 |
+
}
|
411 |
+
|
412 |
+
}
|
413 |
+
return $result;
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Returns JS code in the footer for this concrete action.
|
418 |
+
*
|
419 |
+
* @param string $currentJs previusly generated JS
|
420 |
+
* @return string
|
421 |
+
*/
|
422 |
+
protected function _getAdditionalJs($currentJs) {
|
423 |
+
$js = '';
|
424 |
+
if (!Mage::getStoreConfig('eabi_livehandler/admintools/enabled')) {
|
425 |
+
return $js;
|
426 |
+
}
|
427 |
+
/* @var $adminHelper Mage_Adminhtml_Helper_Data */
|
428 |
+
$adminHelper = Mage::helper('adminhtml');
|
429 |
+
$showProductsText = Mage::helper('eabi_livehandler')->__('Show order info');
|
430 |
+
$showProductsText = htmlspecialchars(str_replace('\\\'', '\'', addslashes($showProductsText)));
|
431 |
+
|
432 |
+
$additionalCssClass = '';
|
433 |
+
if (substr(Mage::getVersion(), 0, 3) == '1.3') {
|
434 |
+
$additionalCssClass = ' eabi_window_bg';
|
435 |
+
}
|
436 |
+
$longOnClicks = array();
|
437 |
+
|
438 |
+
foreach (self::$_allowedActions as $allowedAction) {
|
439 |
+
$actionButtonModel = Mage::getSingleton('eabi_livehandler/action_' . $allowedAction);
|
440 |
+
/* @var $actionButtonModel Eabi_Livehandler_Model_Action_Abstract */
|
441 |
+
if ($actionButtonModel && $actionButtonModel instanceof Eabi_Livehandler_Model_Action_Abstract) {
|
442 |
+
if ($actionButtonModel->getLongOnClick() && strlen($actionButtonModel->getLongOnClick())) {
|
443 |
+
$longOnClicks[$actionButtonModel->getCode()] = $actionButtonModel->getLongOnClick();
|
444 |
+
}
|
445 |
+
}
|
446 |
+
}
|
447 |
+
|
448 |
+
|
449 |
+
|
450 |
+
|
451 |
+
$js .= <<<EOT
|
452 |
+
|
453 |
+
var clickFirst = false, clickLast = false;
|
454 |
+
var eabiAdmintoolsGrid = function() {
|
455 |
+
|
456 |
+
var position = 0,
|
457 |
+
filters = $$('tr.filter').first().childElements(),
|
458 |
+
needs_reload = false,
|
459 |
+
pageNum = parseInt($$('input[name=page]').first().getValue(), 10),
|
460 |
+
pageLimit = parseInt($$('select[name=limit]').first().getValue(), 10),
|
461 |
+
current_products = [];
|
462 |
+
|
463 |
+
if (Control.Modal.current) {
|
464 |
+
Control.Modal.current.close();
|
465 |
+
}
|
466 |
+
|
467 |
+
for (var i = 0, cnt = filters.length; i < cnt; i++) {
|
468 |
+
if (filters[i].select('input[name=billing_name]').length == 1) {
|
469 |
+
position = i;
|
470 |
+
break;
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
|
475 |
+
var rows = $$('table#sales_order_grid_table tbody tr');
|
476 |
+
if (rows.length == 1) {
|
477 |
+
return;
|
478 |
+
}
|
479 |
+
|
480 |
+
for (var i = 0, cnt = rows.length; i < cnt; i++) {
|
481 |
+
rows[i].childElements()[position].insert('<button id="eabi-order_' + rows[i].select('input[class=massaction-checkbox]').first().readAttribute('value') + '" style="float: right;" class="scalable show-hide eabi-order-products" onclick="Event.stop(event); return false;" type="button"><span><b>{$showProductsText}</b></span></button>', { position: 'bottom'})
|
482 |
+
}
|
483 |
+
|
484 |
+
var style_window = function(container, options) {
|
485 |
+
var window_header = new Element('div', { className: 'window_header'});
|
486 |
+
var window_title = new Element('div', { className: 'window_title'});
|
487 |
+
var window_close = new Element('div', { className: 'window_close'});
|
488 |
+
var window_contents = new Element('div', { className: 'window_contents'});
|
489 |
+
|
490 |
+
var w = new Control.Modal(container, Object.extend({
|
491 |
+
className: 'eabi_window{$additionalCssClass}',
|
492 |
+
/*closeOnClick: window_close,*/
|
493 |
+
draggable: window_header,
|
494 |
+
insertRemoteContentAt: window_contents,
|
495 |
+
iframeshim: false,
|
496 |
+
afterOpen: function() {
|
497 |
+
var eabi_order_products = $$('button.eabi-order-products').toArray(),
|
498 |
+
order_id = options.caller.readAttribute('id').split('_')[1],
|
499 |
+
post_params = {'order_id': order_id };
|
500 |
+
if (options.target) {
|
501 |
+
post_params.action = options.target;
|
502 |
+
}
|
503 |
+
if (options.extra_data) {
|
504 |
+
post_params.extra_data = Object.toJSON(options.extra_data);
|
505 |
+
}
|
506 |
+
// window_title.update(container.readAttribute('title'));
|
507 |
+
if (options.caller) {
|
508 |
+
window_close.observe('click', function(event) {
|
509 |
+
if (Control.Modal.current) {
|
510 |
+
Control.Modal.current.close();
|
511 |
+
}
|
512 |
+
if (needs_reload) {
|
513 |
+
window.location.reload();
|
514 |
+
}
|
515 |
+
});
|
516 |
+
new Ajax.Request(action_url, {
|
517 |
+
method: 'post',
|
518 |
+
parameters: post_params,
|
519 |
+
evalJSON: 'force',
|
520 |
+
onSuccess: function(transport) {
|
521 |
+
var html = '';
|
522 |
+
if (transport.responseJSON) {
|
523 |
+
var html = '', json = transport.responseJSON, longClicks = {};
|
524 |
+
if (json.set_location) {
|
525 |
+
setLocation(json.set_location);
|
526 |
+
return;
|
527 |
+
}
|
528 |
+
if (json.success) {
|
529 |
+
html += json.customer_address_html;
|
530 |
+
html += json.header_html;
|
531 |
+
json.products.each(function(item) {
|
532 |
+
html += item.html;
|
533 |
+
});
|
534 |
+
html += json.footer_html;
|
535 |
+
window_contents.update(html);
|
536 |
+
window_title.update(json.title_html);
|
537 |
+
//add the click handlers....
|
538 |
+
|
539 |
+
|
540 |
+
EOT;
|
541 |
+
foreach ($longOnClicks as $key => $longOnClick) {
|
542 |
+
$js .= <<<EOT
|
543 |
+
longClicks[{$this->_encode($key)}] = function(event, caller, json) {
|
544 |
+
{$longOnClick};
|
545 |
+
};
|
546 |
+
|
547 |
+
EOT;
|
548 |
+
}
|
549 |
+
|
550 |
+
|
551 |
+
|
552 |
+
|
553 |
+
$js .= <<<EOT
|
554 |
+
|
555 |
+
window_contents.insert({before: '<span id="eabi_previous" class="eabi_arrow" title="' + {$this->_encode($adminHelper->__('Previous'))} + '" onclick="Podium.keydown(38);"></span><span id="eabi_next" class="eabi_arrow" title="' + {$this->_encode($adminHelper->__('Next'))}+ '" onclick="Podium.keydown(40);"></span>'});
|
556 |
+
|
557 |
+
window_contents.select('.eabi_orderview_actionbutton').each(function(item) {
|
558 |
+
var item_id = item.readAttribute('id'), passed = true;
|
559 |
+
if (item_id) {
|
560 |
+
item.observe('click', function(event) {
|
561 |
+
EOT;
|
562 |
+
//here goes extra long click
|
563 |
+
/*
|
564 |
+
* var longClicks = {
|
565 |
+
* 'comment' : function(event) { function body goes here... },
|
566 |
+
* 'cancel' : function(event) { function body goes here... },
|
567 |
+
* };
|
568 |
+
*
|
569 |
+
* if (longClicks[item_id.replace('eabi_', '')]) {
|
570 |
+
* longClicks[item_id.replace('eabi_', '')](event);
|
571 |
+
* }
|
572 |
+
*
|
573 |
+
*/
|
574 |
+
|
575 |
+
$js .= <<<EOT
|
576 |
+
|
577 |
+
if (longClicks[item_id.replace('eabi_', '')]) {
|
578 |
+
passed = longClicks[item_id.replace('eabi_', '')](event, options.caller, json);
|
579 |
+
}
|
580 |
+
if (passed !== false) {
|
581 |
+
handleButtonClick(item_id.replace('eabi_', ''), options.caller, passed);
|
582 |
+
}
|
583 |
+
event.stop();
|
584 |
+
});
|
585 |
+
}
|
586 |
+
});
|
587 |
+
if (json.needs_reload) {
|
588 |
+
needs_reload = true;
|
589 |
+
}
|
590 |
+
|
591 |
+
} else {
|
592 |
+
window.location.reload();
|
593 |
+
}
|
594 |
+
} else {
|
595 |
+
window.location.reload();
|
596 |
+
}
|
597 |
+
}
|
598 |
+
});
|
599 |
+
}
|
600 |
+
if (options.hasOwnProperty('callerIndex')) {
|
601 |
+
document.observe('keydown', function(event) {
|
602 |
+
var keyCode = event.keyCode;
|
603 |
+
if (keyCode == 38 || keyCode == 37) {
|
604 |
+
if (options.callerIndex > 0) {
|
605 |
+
eabi_order_products[options.callerIndex - 1].click();
|
606 |
+
} else {
|
607 |
+
if (eabi_order_products.length && pageNum > 1) {
|
608 |
+
sales_order_gridJsObject.setPage(pageNum - 1, false);
|
609 |
+
clickLast = true;
|
610 |
+
}
|
611 |
+
}
|
612 |
+
return event.stop();
|
613 |
+
} else if (keyCode == 40 || keyCode == 39) {
|
614 |
+
if (options.callerIndex < (eabi_order_products.length - 1)) {
|
615 |
+
eabi_order_products[options.callerIndex + 1].click();
|
616 |
+
} else {
|
617 |
+
if (eabi_order_products && eabi_order_products.length >= pageLimit) {
|
618 |
+
sales_order_gridJsObject.setPage(pageNum + 1, true);
|
619 |
+
clickFirst = true;
|
620 |
+
}
|
621 |
+
}
|
622 |
+
return event.stop();
|
623 |
+
} else if (keyCode == 27) {
|
624 |
+
//esc key
|
625 |
+
Control.Modal.current.close(event);
|
626 |
+
if (needs_reload) {
|
627 |
+
window.location.reload();
|
628 |
+
}
|
629 |
+
return event.stop();
|
630 |
+
}
|
631 |
+
return event;
|
632 |
+
});
|
633 |
+
}
|
634 |
+
},
|
635 |
+
afterClose: function() {
|
636 |
+
if (options.caller) {
|
637 |
+
options.caller.removeClassName('disabled');
|
638 |
+
}
|
639 |
+
if (options.hasOwnProperty('callerIndex')) {
|
640 |
+
document.stopObserving('keydown');
|
641 |
+
$$('eabi_orderview_actionbutton').each(function(item) {
|
642 |
+
item.stopObserving('click');
|
643 |
+
});
|
644 |
+
window_close.stopObserving('click');
|
645 |
+
}
|
646 |
+
this.destroy();
|
647 |
+
}
|
648 |
+
}, options || {}));
|
649 |
+
|
650 |
+
w.container.insert(window_header);
|
651 |
+
window_header.insert(window_title);
|
652 |
+
window_header.insert(window_close);
|
653 |
+
w.container.insert(window_contents);
|
654 |
+
return w;
|
655 |
+
};
|
656 |
+
$$('button.eabi-order-products').each(function(item, index) {
|
657 |
+
var order_id = item.readAttribute('id').split('_')[1];
|
658 |
+
item.observe('click', function(event) {
|
659 |
+
item.addClassName('disabled');
|
660 |
+
var event_arguments = { title: '', caller: item, callerIndex: index};
|
661 |
+
if (event.memo && event.memo.target) {
|
662 |
+
event_arguments.target = event.memo.target;
|
663 |
+
}
|
664 |
+
var style_window_one = style_window('', event_arguments);
|
665 |
+
style_window_one.open();
|
666 |
+
event.stop();
|
667 |
+
});
|
668 |
+
item.observe('eabi:click', function(event) {
|
669 |
+
item.addClassName('disabled');
|
670 |
+
var event_arguments = { title: '', caller: item, callerIndex: index};
|
671 |
+
if (event.memo && event.memo.target) {
|
672 |
+
event_arguments.target = event.memo.target;
|
673 |
+
}
|
674 |
+
if (event.memo && event.memo.extra_data) {
|
675 |
+
event_arguments.extra_data = event.memo.extra_data;
|
676 |
+
}
|
677 |
+
var style_window_one = style_window('', event_arguments);
|
678 |
+
style_window_one.open();
|
679 |
+
event.stop();
|
680 |
+
});
|
681 |
+
});
|
682 |
+
if (clickFirst) {
|
683 |
+
current_products = $$('button.eabi-order-products').toArray();
|
684 |
+
if (current_products && current_products[0]) {
|
685 |
+
current_products[0].click();
|
686 |
+
}
|
687 |
+
clickFirst = false;
|
688 |
+
}
|
689 |
+
if (clickLast) {
|
690 |
+
current_products = $$('button.eabi-order-products').toArray();
|
691 |
+
if (current_products && current_products.length) {
|
692 |
+
current_products[current_products.length - 1].click();
|
693 |
+
}
|
694 |
+
clickLast = false;
|
695 |
+
}
|
696 |
+
|
697 |
+
|
698 |
+
}; //end of eabiAdminToolsGrid
|
699 |
+
|
700 |
+
var oldInitGridRows = false;
|
701 |
+
if (Control && Control.Modal) {
|
702 |
+
eabiAdmintoolsGrid();
|
703 |
+
oldInitGridRows = sales_order_gridJsObject.initGridRows;
|
704 |
+
}
|
705 |
+
|
706 |
+
if (oldInitGridRows) {
|
707 |
+
sales_order_gridJsObject.initGridRows = function() {
|
708 |
+
$$('button.eabi-order-products').each(function(item) {
|
709 |
+
item.stopObserving('click');
|
710 |
+
item.stopObserving('eabi:click');
|
711 |
+
});
|
712 |
+
oldInitGridRows();
|
713 |
+
eabiAdmintoolsGrid();
|
714 |
+
};
|
715 |
+
} else if (Control && Control.Modal) {
|
716 |
+
var oldInitGridRows = varienGrid.prototype.reload;
|
717 |
+
varienGrid.prototype.reload = function(url) {
|
718 |
+
$$('button.eabi-order-products').each(function(item) {
|
719 |
+
item.stopObserving('click');
|
720 |
+
item.stopObserving('eabi:click');
|
721 |
+
});
|
722 |
+
|
723 |
+
if (!this.reloadParams) {
|
724 |
+
this.reloadParams = {form_key: FORM_KEY};
|
725 |
+
}
|
726 |
+
else {
|
727 |
+
this.reloadParams.form_key = FORM_KEY;
|
728 |
+
}
|
729 |
+
url = url || this.url;
|
730 |
+
if(this.useAjax){
|
731 |
+
new Ajax.Request(url + ((url.match(new RegExp('\\\\?')) ? '&ajax=true' : '?ajax=true') ), {
|
732 |
+
loaderArea: this.containerId,
|
733 |
+
parameters: this.reloadParams || {},
|
734 |
+
evalScripts: true,
|
735 |
+
onFailure: this._processFailure.bind(this),
|
736 |
+
onComplete: this.initGrid.bind(this),
|
737 |
+
onSuccess: function(transport) {
|
738 |
+
try {
|
739 |
+
if (transport.responseText.isJSON()) {
|
740 |
+
var response = transport.responseText.evalJSON()
|
741 |
+
if (response.error) {
|
742 |
+
alert(response.message);
|
743 |
+
}
|
744 |
+
if(response.ajaxExpired && response.ajaxRedirect) {
|
745 |
+
setLocation(response.ajaxRedirect);
|
746 |
+
}
|
747 |
+
} else {
|
748 |
+
$(this.containerId).update(transport.responseText);
|
749 |
+
eabiAdmintoolsGrid();
|
750 |
+
}
|
751 |
+
}
|
752 |
+
catch (e) {
|
753 |
+
$(this.containerId).update(transport.responseText);
|
754 |
+
}
|
755 |
+
}.bind(this)
|
756 |
+
});
|
757 |
+
return;
|
758 |
+
}
|
759 |
+
else{
|
760 |
+
if(this.reloadParams){
|
761 |
+
\$H(this.reloadParams).each(function(pair){
|
762 |
+
url = this.addVarToUrl(pair.key, pair.value);
|
763 |
+
}.bind(this));
|
764 |
+
}
|
765 |
+
location.href = url;
|
766 |
+
}
|
767 |
+
|
768 |
+
|
769 |
+
};
|
770 |
+
|
771 |
+
}
|
772 |
+
|
773 |
+
//handle the clicks......
|
774 |
+
function handleButtonClick(call_action, caller_button, passed) {
|
775 |
+
//make ajax request
|
776 |
+
caller_button.fire('eabi:click', { target: call_action, extra_data: passed});
|
777 |
+
}
|
778 |
+
|
779 |
+
|
780 |
+
|
781 |
+
|
782 |
+
EOT;
|
783 |
+
|
784 |
+
|
785 |
+
return $js;
|
786 |
+
}
|
787 |
+
|
788 |
+
private function __makeActionButton($title, $onclick = '', $cssClass = '', $id = '') {
|
789 |
+
$html = '';
|
790 |
+
|
791 |
+
$onclick = htmlspecialchars(str_replace('\\\'', '\'', addslashes($onclick)));
|
792 |
+
|
793 |
+
$html .= <<<EOT
|
794 |
+
<button class="scalable eabi_orderview_actionbutton {$cssClass}" id="{$id}" type="button" onclick="{$onclick}"><span>{$title}</span></button>
|
795 |
+
|
796 |
+
EOT;
|
797 |
+
return $html;
|
798 |
+
}
|
799 |
+
|
800 |
+
protected function _encode($input) {
|
801 |
+
return json_encode($input);
|
802 |
+
|
803 |
+
}
|
804 |
+
|
805 |
+
/**
|
806 |
+
*
|
807 |
+
* @return Eabi_Livehandler_Helper_Data
|
808 |
+
*/
|
809 |
+
protected function getEabi() {
|
810 |
+
return Mage::helper('eabi');
|
811 |
+
}
|
812 |
+
|
813 |
+
}
|
814 |
+
|
app/code/community/Eabi/Livehandler/Model/System/Config/Backend/Button.php
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Description of Button
|
30 |
+
*
|
31 |
+
* @author Matis
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Model_System_Config_Backend_Button extends Mage_Adminhtml_Model_System_Config_Backend_Serialized_Array {
|
34 |
+
protected $_eventPrefix = 'eabi_livehandler_system_config_backend_button';
|
35 |
+
|
36 |
+
protected function _afterLoad() {
|
37 |
+
parent::_afterLoad();
|
38 |
+
// Zend_Debug::dump($this->getValue());
|
39 |
+
$dirnames = array(
|
40 |
+
Mage::getBaseDir('code').'/community/Eabi/Livehandler/Model/Action',
|
41 |
+
Mage::getBaseDir('code').'/local/Eabi/Livehandler/Model/Action',
|
42 |
+
);
|
43 |
+
$foundNames = array();
|
44 |
+
foreach ($dirnames as $dirname) {
|
45 |
+
if (is_dir($dirname)) {
|
46 |
+
$directoryLister = new Varien_Directory_Collection($dirname, true);
|
47 |
+
$filenames = $directoryLister->filesPaths();
|
48 |
+
foreach ($filenames as $filename) {
|
49 |
+
$className = str_replace(array($dirname, '\\'), array('', '/'), $filename);
|
50 |
+
if (strpos($className, '.php') !== false) {
|
51 |
+
$className = ltrim(strtolower(str_replace(array('.php', '/'), array('', '_'), $className)), '_');
|
52 |
+
if ($className != 'abstract') {
|
53 |
+
$foundNames[$className] = $className;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
}
|
59 |
+
}
|
60 |
+
$values = $this->getValue();
|
61 |
+
$existingValues = array();
|
62 |
+
$valuesToRemove = array();
|
63 |
+
if (is_array($values)) {
|
64 |
+
uasort($values, array(__CLASS__, '_sortAction'));
|
65 |
+
|
66 |
+
foreach ($values as $key => $value) {
|
67 |
+
$existingValues[$value['button_name']] = $value['button_name'];
|
68 |
+
$testModel = Mage::getModel('eabi_livehandler/action_'.$value['button_name']);
|
69 |
+
if (!$testModel || !($testModel instanceof Eabi_Livehandler_Model_Action_Abstract)) {
|
70 |
+
$valuesToRemove[] = $key;
|
71 |
+
}
|
72 |
+
|
73 |
+
}
|
74 |
+
}
|
75 |
+
if (count($foundNames) && !is_array($values)) {
|
76 |
+
$values = array();
|
77 |
+
}
|
78 |
+
$valueAdded = false;
|
79 |
+
foreach ($foundNames as $foundName) {
|
80 |
+
if (!isset($existingValues[$foundName])) {
|
81 |
+
$testModel = Mage::getModel('eabi_livehandler/action_'.$foundName);
|
82 |
+
if ($testModel && $testModel instanceof Eabi_Livehandler_Model_Action_Abstract) {
|
83 |
+
$values['_' . time() . '_' . mt_rand(0, 999)] = array(
|
84 |
+
'button_name' => $foundName,
|
85 |
+
'sort_order' => "0",
|
86 |
+
'disabled' => "0"
|
87 |
+
);
|
88 |
+
$valueAdded = true;
|
89 |
+
}
|
90 |
+
|
91 |
+
}
|
92 |
+
}
|
93 |
+
foreach ($valuesToRemove as $valueToRemove) {
|
94 |
+
unset($values[$valueToRemove]);
|
95 |
+
}
|
96 |
+
if ($valueAdded || count($valuesToRemove) || true) {
|
97 |
+
$this->setValue($values);
|
98 |
+
}
|
99 |
+
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
public function isValueChanged() {
|
104 |
+
$oldValue = @unserialize($this->getOldValue());
|
105 |
+
if (is_array($oldValue)) {
|
106 |
+
return $oldValue != $this->getValue();
|
107 |
+
}
|
108 |
+
return parent::isValueChanged();
|
109 |
+
}
|
110 |
+
|
111 |
+
|
112 |
+
public static function _sortAction($a, $b) {
|
113 |
+
if ((bool)$a['disabled'] && !(bool)$b['disabled']) {
|
114 |
+
return 1;
|
115 |
+
}
|
116 |
+
if (!(bool)$a['disabled'] && (bool)$b['disabled']) {
|
117 |
+
return -1;
|
118 |
+
}
|
119 |
+
if ((int)$a['sort_order'] == (int)$b['sort_order']) {
|
120 |
+
return 0;
|
121 |
+
}
|
122 |
+
return (int)$a['sort_order'] < (int)$b['sort_order']?-1:1;
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
}
|
127 |
+
|
app/code/community/Eabi/Livehandler/controllers/Adminhtml/LivehandlerController.php
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* <p>Handles the AJAX request defined for the backend (from database table eabi_livehandler)</p>
|
30 |
+
* <p>Security model: If Page itself can be displayed, then it is allowed to run actions, which are bound to current Livehandler model. If user switches page, then current model actions cannot be run any more.</p>
|
31 |
+
* <p>If user does not show any activity for Eabi_Livehandler_IndexController::ALLOWED time seconds, then actions cannot be run after timeout.</p>
|
32 |
+
*
|
33 |
+
* @author matishalmann
|
34 |
+
*/
|
35 |
+
class Eabi_Livehandler_Adminhtml_LivehandlerController extends Mage_Adminhtml_Controller_Action {
|
36 |
+
const ALLOWED_TIME = 1800;
|
37 |
+
protected function _initAction() {
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
+
|
41 |
+
public function processAction() {
|
42 |
+
$result = array();
|
43 |
+
if (!$this->_getEabi()->getConfigData('eabi_livehandler/main/enabled')) {
|
44 |
+
throw new Exception('Module Eabi Livehandler is not enabled');
|
45 |
+
}
|
46 |
+
/*
|
47 |
+
* Check if the process is in Session allowed list.
|
48 |
+
*
|
49 |
+
*/
|
50 |
+
$session = Mage::getSingleton('core/session');
|
51 |
+
$time = time();
|
52 |
+
|
53 |
+
$processName = base64_decode($this->getRequest()->getParam('__path'));
|
54 |
+
$processEntries = $session->getData('eabi_livehandler_entries');
|
55 |
+
$website = Mage::app()->getStore()->getWebsiteId();
|
56 |
+
$store = Mage::app()->getStore()->getStoreId();
|
57 |
+
|
58 |
+
|
59 |
+
if (is_array($processEntries) && isset($processEntries[$processName]) && $time - $processEntries[$processName] < self::ALLOWED_TIME) {
|
60 |
+
|
61 |
+
|
62 |
+
//execute the action.
|
63 |
+
$isAdmin = true;
|
64 |
+
$model = $processName;
|
65 |
+
|
66 |
+
//get action by action name, website, store, is_admin = false
|
67 |
+
$actionsCollection = Mage::getModel('eabi_livehandler/entry')->getCollection()->setModelFilter($model, $isAdmin, $website, $store);
|
68 |
+
|
69 |
+
$classesRan = array();
|
70 |
+
|
71 |
+
$result = array();
|
72 |
+
foreach ($actionsCollection as $action) {
|
73 |
+
$action->load($action->getId());
|
74 |
+
if (isset($classesRan[$action->getModelClass()])) {
|
75 |
+
continue;
|
76 |
+
}
|
77 |
+
|
78 |
+
|
79 |
+
if (!isset($result['_is_error']) || !$result['_is_error']) {
|
80 |
+
$processEntries[$processName] = $time;
|
81 |
+
$result = $action->runAdmin($this->getRequest()->getPost());
|
82 |
+
}
|
83 |
+
$classesRan[$action->getModelClass()] = true;
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
|
89 |
+
Mage::getSingleton('core/session')->setData('eabi_livehandler_entries', $processEntries);
|
90 |
+
} else {
|
91 |
+
$result['_is_error'] = true;
|
92 |
+
}
|
93 |
+
|
94 |
+
|
95 |
+
echo Zend_Json::encode($result);
|
96 |
+
die();
|
97 |
+
}
|
98 |
+
/**
|
99 |
+
*
|
100 |
+
* @return Eabi_Livehandler_Helper_Data
|
101 |
+
*/
|
102 |
+
protected function _getEabi() {
|
103 |
+
return Mage::helper('eabi');
|
104 |
+
}
|
105 |
+
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
|
app/code/community/Eabi/Livehandler/controllers/Adminhtml/RemoveController.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* <p>Removes old livehandler from app/local folder</p>
|
30 |
+
*
|
31 |
+
* @author matishalmann
|
32 |
+
*/
|
33 |
+
class Eabi_Livehandler_Adminhtml_RemoveController extends Mage_Adminhtml_Controller_Action {
|
34 |
+
protected function _initAction() {
|
35 |
+
return $this;
|
36 |
+
}
|
37 |
+
|
38 |
+
public function removeAction() {
|
39 |
+
$result = array('status' => 'failed');
|
40 |
+
if ($this->getRequest()->isPost() && $this->getRequest()->getPost('remove') == 'true') {
|
41 |
+
$dirName = Mage::getBaseDir('code').'/local/Eabi/Livehandler';
|
42 |
+
if (is_dir($dirName) && file_exists($dirName.'/etc/config.xml')) {
|
43 |
+
$directory = new Varien_Io_File();
|
44 |
+
$deleteResult = $directory->rmdir($dirName, true);
|
45 |
+
if ($deleteResult) {
|
46 |
+
$result['status'] = 'success';
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
}
|
51 |
+
$this->getResponse()->setRawHeader('Content-type: application/json');
|
52 |
+
$this->getResponse()->setBody(json_encode($result));
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
*
|
58 |
+
* @return Eabi_Livehandler_Helper_Data
|
59 |
+
*/
|
60 |
+
protected function _getEabi() {
|
61 |
+
return Mage::helper('eabi');
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
}
|
66 |
+
|
67 |
+
|
app/code/community/Eabi/Livehandler/controllers/IndexController.php
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
/**
|
29 |
+
* <p>Handles the AJAX request defined for the frontend (from database table eabi_livehandler)</p>
|
30 |
+
* <p>Security model: If Page itself can be displayed, then it is allowed to run actions, which are bound to current Livehandler model. If user switches page, then current model actions cannot be run any more.</p>
|
31 |
+
* <p>If user does not show any activity for Eabi_Livehandler_IndexController::ALLOWED time seconds, then actions cannot be run after timeout.</p>
|
32 |
+
*
|
33 |
+
*
|
34 |
+
* @author matishalmann
|
35 |
+
*/
|
36 |
+
class Eabi_Livehandler_IndexController extends Mage_Core_Controller_Front_Action {
|
37 |
+
const ALLOWED_TIME = 1800;
|
38 |
+
public function processAction() {
|
39 |
+
$result = array();
|
40 |
+
if (!$this->_getEabi()->getConfigData('eabi_livehandler/main/enabled')) {
|
41 |
+
throw new Exception('Module Eabi Livehandler is not enabled');
|
42 |
+
}
|
43 |
+
/*
|
44 |
+
* Check if the process is in Session allowed list.
|
45 |
+
*
|
46 |
+
*/
|
47 |
+
$session = Mage::getSingleton('core/session');
|
48 |
+
$time = time();
|
49 |
+
|
50 |
+
$processName = base64_decode($this->getRequest()->getParam('__path'));
|
51 |
+
// $processName = $this->getRequest()->getParam('processName');
|
52 |
+
$processEntries = $session->getData('eabi_livehandler_entries');
|
53 |
+
$website = Mage::app()->getStore()->getWebsiteId();
|
54 |
+
$store = Mage::app()->getStore()->getStoreId();
|
55 |
+
|
56 |
+
|
57 |
+
if (is_array($processEntries) && isset($processEntries[$processName]) && $time - $processEntries[$processName] < self::ALLOWED_TIME) {
|
58 |
+
|
59 |
+
|
60 |
+
//execute the action.
|
61 |
+
$isAdmin = false;
|
62 |
+
$model = $processName;
|
63 |
+
|
64 |
+
//get action by action name, website, store, is_admin = false
|
65 |
+
$actionsCollection = Mage::getModel('eabi_livehandler/entry')->getCollection()->setModelFilter($model, $isAdmin, $website, $store);
|
66 |
+
|
67 |
+
$result = array();
|
68 |
+
$classesRan = array();
|
69 |
+
foreach ($actionsCollection as $action) {
|
70 |
+
$action->load($action->getId());
|
71 |
+
if (isset($classesRan[$action->getModelClass()])) {
|
72 |
+
continue;
|
73 |
+
}
|
74 |
+
|
75 |
+
if (!isset($result['_is_error']) || !$result['_is_error']) {
|
76 |
+
$processEntries[$processName] = $time;
|
77 |
+
$action->runPublic($this->getRequest()->getPost());
|
78 |
+
}
|
79 |
+
$classesRan[$action->getModelClass()] = true;
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
|
85 |
+
Mage::getSingleton('core/session')->setData('eabi_livehandler_entries', $processEntries);
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
echo Zend_Json::encode($result);
|
90 |
+
die();
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
*
|
95 |
+
* @return Eabi_Livehandler_Helper_Data
|
96 |
+
*/
|
97 |
+
protected function _getEabi() {
|
98 |
+
return Mage::helper('eabi');
|
99 |
+
}
|
100 |
+
|
101 |
+
}
|
102 |
+
|
app/code/community/Eabi/Livehandler/etc/config.xml
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
@category Eabi
|
5 |
+
@package Eabi_Livehandler
|
6 |
+
@author Aktsiamaailm OU
|
7 |
+
@licence http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
|
9 |
+
*/
|
10 |
+
-->
|
11 |
+
|
12 |
+
|
13 |
+
<config>
|
14 |
+
<modules>
|
15 |
+
<Eabi_Livehandler>
|
16 |
+
<version>0.1.1</version>
|
17 |
+
</Eabi_Livehandler>
|
18 |
+
</modules>
|
19 |
+
|
20 |
+
<admin>
|
21 |
+
<routers>
|
22 |
+
<eabi_livehandler>
|
23 |
+
<use>admin</use>
|
24 |
+
<args>
|
25 |
+
<module>Eabi_Livehandler</module>
|
26 |
+
<frontName>eabi_livehandler</frontName>
|
27 |
+
</args>
|
28 |
+
</eabi_livehandler>
|
29 |
+
</routers>
|
30 |
+
</admin>
|
31 |
+
|
32 |
+
<frontend>
|
33 |
+
<routers>
|
34 |
+
<eabi_livehandler>
|
35 |
+
<use>standard</use>
|
36 |
+
<args>
|
37 |
+
<module>Eabi_Livehandler</module>
|
38 |
+
<frontName>eabi_livehandler</frontName>
|
39 |
+
</args>
|
40 |
+
</eabi_livehandler>
|
41 |
+
</routers>
|
42 |
+
<layout>
|
43 |
+
<updates>
|
44 |
+
<eabi_livehandler>
|
45 |
+
<file>eabi_livehandler.xml</file>
|
46 |
+
</eabi_livehandler>
|
47 |
+
</updates>
|
48 |
+
</layout>
|
49 |
+
</frontend>
|
50 |
+
|
51 |
+
<adminhtml>
|
52 |
+
<translate>
|
53 |
+
<modules>
|
54 |
+
<eabi_livehandler>
|
55 |
+
<files>
|
56 |
+
<default>Eabi_Livehandler.csv</default>
|
57 |
+
</files>
|
58 |
+
</eabi_livehandler>
|
59 |
+
</modules>
|
60 |
+
</translate>
|
61 |
+
<acl>
|
62 |
+
<resources>
|
63 |
+
<all>
|
64 |
+
<title>Allow Everything</title>
|
65 |
+
</all>
|
66 |
+
<admin>
|
67 |
+
<children>
|
68 |
+
<system>
|
69 |
+
<children>
|
70 |
+
<config>
|
71 |
+
<children>
|
72 |
+
<eabi_livehandler>
|
73 |
+
<title>Live Handler from Eabi.ee</title>
|
74 |
+
</eabi_livehandler>
|
75 |
+
</children>
|
76 |
+
</config>
|
77 |
+
</children>
|
78 |
+
</system>
|
79 |
+
</children>
|
80 |
+
</admin>
|
81 |
+
</resources>
|
82 |
+
</acl>
|
83 |
+
<layout>
|
84 |
+
<updates>
|
85 |
+
<eabi_livehandler>
|
86 |
+
<file>eabi_livehandler.xml</file>
|
87 |
+
</eabi_livehandler>
|
88 |
+
</updates>
|
89 |
+
</layout>
|
90 |
+
|
91 |
+
</adminhtml>
|
92 |
+
|
93 |
+
<global>
|
94 |
+
<models>
|
95 |
+
<eabi_livehandler>
|
96 |
+
<class>Eabi_Livehandler_Model</class>
|
97 |
+
<resourceModel>eabi_livehandler_mysql4</resourceModel>
|
98 |
+
</eabi_livehandler>
|
99 |
+
<eabi_livehandler_mysql4>
|
100 |
+
<class>Eabi_Livehandler_Model_Mysql4</class>
|
101 |
+
<entities>
|
102 |
+
<entry>
|
103 |
+
<table>eabi_livehandler</table>
|
104 |
+
</entry>
|
105 |
+
</entities>
|
106 |
+
</eabi_livehandler_mysql4>
|
107 |
+
</models>
|
108 |
+
<blocks>
|
109 |
+
<eabi_livehandler>
|
110 |
+
<class>Eabi_Livehandler_Block</class>
|
111 |
+
</eabi_livehandler>
|
112 |
+
</blocks>
|
113 |
+
<resources>
|
114 |
+
<eabi_livehandler_setup>
|
115 |
+
<setup>
|
116 |
+
<module>Eabi_Livehandler</module>
|
117 |
+
</setup>
|
118 |
+
<connection>
|
119 |
+
<use>core_setup</use>
|
120 |
+
</connection>
|
121 |
+
</eabi_livehandler_setup>
|
122 |
+
<eabi_livehandler_write>
|
123 |
+
<setup>
|
124 |
+
<module>Eabi_Livehandler</module>
|
125 |
+
</setup>
|
126 |
+
<connection>
|
127 |
+
<use>core_write</use>
|
128 |
+
</connection>
|
129 |
+
</eabi_livehandler_write>
|
130 |
+
<eabi_livehandler_read>
|
131 |
+
<setup>
|
132 |
+
<module>Eabi_Livehandler</module>
|
133 |
+
</setup>
|
134 |
+
<connection>
|
135 |
+
<use>core_read</use>
|
136 |
+
</connection>
|
137 |
+
</eabi_livehandler_read>
|
138 |
+
</resources>
|
139 |
+
<helpers>
|
140 |
+
<eabi>
|
141 |
+
<class>Eabi_Livehandler_Helper</class>
|
142 |
+
</eabi>
|
143 |
+
<eabi_livehandler>
|
144 |
+
<class>Eabi_Livehandler_Helper</class>
|
145 |
+
</eabi_livehandler>
|
146 |
+
</helpers>
|
147 |
+
<translate>
|
148 |
+
<modules>
|
149 |
+
<eabi_livehandler>
|
150 |
+
<files>
|
151 |
+
<default>Eabi_Livehandler.csv</default>
|
152 |
+
</files>
|
153 |
+
</eabi_livehandler>
|
154 |
+
</modules>
|
155 |
+
</translate>
|
156 |
+
</global>
|
157 |
+
<default>
|
158 |
+
<eabi_livehandler>
|
159 |
+
<main>
|
160 |
+
<enabled>1</enabled>
|
161 |
+
</main>
|
162 |
+
<admintools>
|
163 |
+
<enabled>1</enabled>
|
164 |
+
<open_in_new>1</open_in_new>
|
165 |
+
<buttons_url>http://en.e-abi.ee/magento/better-order-management.html</buttons_url>
|
166 |
+
</admintools>
|
167 |
+
</eabi_livehandler>
|
168 |
+
</default>
|
169 |
+
</config>
|
app/code/community/Eabi/Livehandler/etc/system.xml
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
@category Eabi
|
5 |
+
@package Eabi_Livehandler
|
6 |
+
@author Aktsiamaailm OU
|
7 |
+
@licence http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
|
9 |
+
*/
|
10 |
+
-->
|
11 |
+
|
12 |
+
|
13 |
+
<config>
|
14 |
+
<tabs>
|
15 |
+
<eabi translate="label" module="eabi_livehandler">
|
16 |
+
<label>Eabi Moodulid</label>
|
17 |
+
<sort_order>300</sort_order>
|
18 |
+
</eabi>
|
19 |
+
</tabs>
|
20 |
+
<sections>
|
21 |
+
<eabi_livehandler translate="label" module="eabi_livehandler">
|
22 |
+
<label>Eabi Livehandler</label>
|
23 |
+
<tab>eabi</tab>
|
24 |
+
<sort_order>340</sort_order>
|
25 |
+
<show_in_default>1</show_in_default>
|
26 |
+
<show_in_website>1</show_in_website>
|
27 |
+
<show_in_store>1</show_in_store>
|
28 |
+
<groups>
|
29 |
+
<main translate="label" module="eabi_livehandler">
|
30 |
+
<label>Global Livehandler settings</label>
|
31 |
+
<tab>eabi</tab>
|
32 |
+
<sort_order>0</sort_order>
|
33 |
+
<show_in_default>1</show_in_default>
|
34 |
+
<show_in_website>1</show_in_website>
|
35 |
+
<show_in_store>1</show_in_store>
|
36 |
+
<fields>
|
37 |
+
<enabled translate="label">
|
38 |
+
<label>Enabled</label>
|
39 |
+
<frontend_type>select</frontend_type>
|
40 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
41 |
+
<sort_order>10</sort_order>
|
42 |
+
<show_in_default>1</show_in_default>
|
43 |
+
<show_in_website>0</show_in_website>
|
44 |
+
<show_in_store>0</show_in_store>
|
45 |
+
</enabled>
|
46 |
+
</fields>
|
47 |
+
</main>
|
48 |
+
<admintools translate="label" module="eabi_livehandler">
|
49 |
+
<label>Admin Order Grid Helper</label>
|
50 |
+
<tab>eabi</tab>
|
51 |
+
<sort_order>340</sort_order>
|
52 |
+
<show_in_default>1</show_in_default>
|
53 |
+
<show_in_website>1</show_in_website>
|
54 |
+
<show_in_store>1</show_in_store>
|
55 |
+
<comment><![CDATA[
|
56 |
+
<a href="http://www.e-abi.ee" target="_blank"><IMG border="0" src="http://www.e-abi.ee/skin/frontend/default/electronics3/images/logo-web.png"></a>
|
57 |
+
<div style="margin-top:4px;margin-bottom:4px; color:gray;"></div>
|
58 |
+
<div style="margin-top:4px;"><b>Aktsiamaailm OÜ, <a href="mailto:info@e-abi.ee">info@e-abi.ee</a></b></div>
|
59 |
+
<hr /><br />
|
60 |
+
|
61 |
+
]]>
|
62 |
+
</comment>
|
63 |
+
<fields>
|
64 |
+
<enabled translate="label">
|
65 |
+
<label>Enabled</label>
|
66 |
+
<frontend_type>select</frontend_type>
|
67 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
68 |
+
<sort_order>1</sort_order>
|
69 |
+
<show_in_default>1</show_in_default>
|
70 |
+
<show_in_website>0</show_in_website>
|
71 |
+
<show_in_store>0</show_in_store>
|
72 |
+
</enabled>
|
73 |
+
<open_in_new translate="label">
|
74 |
+
<label>Open Order in new window when clicking on Order status</label>
|
75 |
+
<frontend_type>select</frontend_type>
|
76 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
77 |
+
<sort_order>2</sort_order>
|
78 |
+
<show_in_default>1</show_in_default>
|
79 |
+
<show_in_website>0</show_in_website>
|
80 |
+
<show_in_store>0</show_in_store>
|
81 |
+
</open_in_new>
|
82 |
+
<buttons translate="">
|
83 |
+
<label></label>
|
84 |
+
<frontend_model>eabi_livehandler/adminhtml_config_form_field_button</frontend_model>
|
85 |
+
<backend_model>eabi_livehandler/system_config_backend_button</backend_model>
|
86 |
+
<sort_order>3</sort_order>
|
87 |
+
<show_in_default>1</show_in_default>
|
88 |
+
<show_in_website>0</show_in_website>
|
89 |
+
<show_in_store>0</show_in_store>
|
90 |
+
</buttons>
|
91 |
+
<removal translate="">
|
92 |
+
<label></label>
|
93 |
+
<frontend_model>eabi_livehandler/adminhtml_config_form_field_remove</frontend_model>
|
94 |
+
<sort_order>4</sort_order>
|
95 |
+
<show_in_default>1</show_in_default>
|
96 |
+
<show_in_website>0</show_in_website>
|
97 |
+
<show_in_store>0</show_in_store>
|
98 |
+
</removal>
|
99 |
+
</fields>
|
100 |
+
|
101 |
+
</admintools>
|
102 |
+
|
103 |
+
</groups>
|
104 |
+
</eabi_livehandler>
|
105 |
+
</sections>
|
106 |
+
|
107 |
+
</config>
|
app/code/community/Eabi/Livehandler/sql/eabi_livehandler_setup/mysql4-install-0.1.0.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
$installer = $this;
|
29 |
+
|
30 |
+
$installer->startSetup();
|
31 |
+
|
32 |
+
$installer->run("
|
33 |
+
DROP TABLE IF EXISTS {$this->getTable('eabi_livehandler')};
|
34 |
+
|
35 |
+
CREATE TABLE {$this->getTable('eabi_livehandler')} (
|
36 |
+
`id` int(11) unsigned NOT NULL auto_increment,
|
37 |
+
`name` varchar(255) NOT NULL,
|
38 |
+
`is_enabled` tinyint(1) unsigned NOT NULL default 0,
|
39 |
+
`is_admin` tinyint(1) unsigned NOT NULL default 0,
|
40 |
+
`request_var` varchar(255) NOT NULL,
|
41 |
+
`store_id` int(11) unsigned NOT NULL default 0,
|
42 |
+
`website_id` int(11) unsigned NOT NULL default 0,
|
43 |
+
`model_class` varchar(255) NULL,
|
44 |
+
`created_time` datetime NULL,
|
45 |
+
`update_time` datetime NULL,
|
46 |
+
`cached_attributes` text NULL,
|
47 |
+
`parameters` text NULL,
|
48 |
+
`css` text NULL,
|
49 |
+
`js` text NULL,
|
50 |
+
`html` text NULL,
|
51 |
+
|
52 |
+
PRIMARY KEY (`id`)
|
53 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
54 |
+
|
55 |
+
");
|
56 |
+
|
57 |
+
|
58 |
+
$installer->endSetup();
|
app/code/community/Eabi/Livehandler/sql/eabi_livehandler_setup/mysql4-upgrade-0.1.0-0.1.1.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* E-Abi (Aktsiamaailm LLC)
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to info@e-abi.ee so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade this module to newer
|
18 |
+
* versions in the future.
|
19 |
+
*
|
20 |
+
* @category Eabi
|
21 |
+
* @package Eabi_Livehandler
|
22 |
+
* @copyright Copyright (c) 2013 Aktsiamaailm LLC (http://en.e-abi.ee/)
|
23 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
24 |
+
* @author Matis Halmann <info@e-abi.ee>
|
25 |
+
*
|
26 |
+
*/
|
27 |
+
|
28 |
+
$installer = $this;
|
29 |
+
|
30 |
+
$installer->startSetup();
|
31 |
+
|
32 |
+
$installer->run("
|
33 |
+
|
34 |
+
DELETE FROM {$this->getTable('eabi_livehandler')} WHERE model_class = 'eabi_admintools/ordergrid';
|
35 |
+
|
36 |
+
INSERT INTO {$this->getTable('eabi_livehandler')}
|
37 |
+
(name, is_enabled, is_admin, request_var, model_class, store_id, website_id, created_time, update_time)
|
38 |
+
VALUES
|
39 |
+
('Adminhtml Sales Order Grid show products', 1, 1, 'adminhtml/sales_order/index', 'eabi_livehandler/ordergrid', 0, 0, NOW(), NOW());
|
40 |
+
|
41 |
+
INSERT INTO {$this->getTable('eabi_livehandler')}
|
42 |
+
(name, is_enabled, is_admin, request_var, model_class, store_id, website_id, created_time, update_time)
|
43 |
+
VALUES
|
44 |
+
('Adminhtml Sales Order Grid show products', 1, 1, 'adminhtml/sales_order/view', 'eabi_livehandler/ordergrid', 0, 0, NOW(), NOW());
|
45 |
+
|
46 |
+
|
47 |
+
");
|
48 |
+
|
49 |
+
|
50 |
+
$installer->endSetup();
|
app/design/adminhtml/default/default/layout/eabi_livehandler.xml
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
Käesoleva loomingu autoriõigused kuuluvad Matis Halmannile ja Aktsiamaailm OU-le
|
4 |
+
Litsentsitingimused on saadaval http://www.e-abi.ee/litsents
|
5 |
+
-->
|
6 |
+
|
7 |
+
|
8 |
+
<layout version="0.1.0">
|
9 |
+
<default>
|
10 |
+
<reference name="before_body_end">
|
11 |
+
<block type="eabi_livehandler/footer" name="eabi_livehandler_footer" as="eabi_livehandler_footer" />
|
12 |
+
</reference>
|
13 |
+
</default>
|
14 |
+
<adminhtml_sales_order_index>
|
15 |
+
<reference name="head">
|
16 |
+
<action method="addJs">
|
17 |
+
<script>livepipe/livepipe.js</script>
|
18 |
+
</action>
|
19 |
+
<action method="addJs">
|
20 |
+
<script>livepipe/window.js</script>
|
21 |
+
</action>
|
22 |
+
<action method="addJs">
|
23 |
+
<script>eabi_js/crossBrowser_initKeyboardEvent.js</script>
|
24 |
+
</action>
|
25 |
+
<action method="addCss">
|
26 |
+
<name>eabi_admintools.css</name>
|
27 |
+
</action>
|
28 |
+
</reference>
|
29 |
+
</adminhtml_sales_order_index>
|
30 |
+
|
31 |
+
|
32 |
+
</layout>
|
app/design/frontend/base/default/layout/eabi_livehandler.xml
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
Käesoleva loomingu autoriõigused kuuluvad Matis Halmannile ja Aktsiamaailm OU-le
|
4 |
+
Litsentsitingimused on saadaval http://www.e-abi.ee/litsents
|
5 |
+
-->
|
6 |
+
|
7 |
+
|
8 |
+
<layout version="0.1.0">
|
9 |
+
<default>
|
10 |
+
<reference name="before_body_end">
|
11 |
+
<block type="eabi_livehandler/footer" name="eabi_livehandler_footer" as="eabi_livehandler_footer" />
|
12 |
+
</reference>
|
13 |
+
</default>
|
14 |
+
|
15 |
+
|
16 |
+
</layout>
|
app/design/frontend/default/default/layout/eabi_livehandler.xml
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
Käesoleva loomingu autoriõigused kuuluvad Matis Halmannile ja Aktsiamaailm OU-le
|
4 |
+
Litsentsitingimused on saadaval http://www.e-abi.ee/litsents
|
5 |
+
-->
|
6 |
+
|
7 |
+
|
8 |
+
<layout version="0.1.0">
|
9 |
+
<default>
|
10 |
+
<reference name="before_body_end">
|
11 |
+
<block type="eabi_livehandler/footer" name="eabi_livehandler_footer" as="eabi_livehandler_footer" />
|
12 |
+
</reference>
|
13 |
+
</default>
|
14 |
+
|
15 |
+
|
16 |
+
</layout>
|
app/etc/modules/Eabi_Livehandler.xml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
@category Eabi
|
5 |
+
@package Eabi_Livehandler
|
6 |
+
@author Aktsiamaailm OU
|
7 |
+
@licence http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
|
9 |
+
*/
|
10 |
+
-->
|
11 |
+
|
12 |
+
|
13 |
+
<config>
|
14 |
+
<modules>
|
15 |
+
<Eabi_Livehandler>
|
16 |
+
<active>true</active>
|
17 |
+
<codePool>community</codePool>
|
18 |
+
<version>0.1.1</version>
|
19 |
+
</Eabi_Livehandler>
|
20 |
+
</modules>
|
21 |
+
</config>
|
app/locale/en_US/Eabi_Livehandler.csv
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Enabled","Enabled"
|
2 |
+
"Global Livehandler settings","Global Livehandler settings"
|
3 |
+
"Eabi Livehandler","Eabi Livehandler"
|
4 |
+
"Show order info","Show order info"
|
5 |
+
"Invalid action","Invalid action"
|
6 |
+
"Not applicable","Not applicable"
|
7 |
+
"Email Invoice","Email Invoice"
|
8 |
+
"Admin Order Grid Helper","Admin Order Grid Helper"
|
9 |
+
"Open Order in new window when clicking on Order status","Open Order in new window when clicking on Order status"
|
10 |
+
"Capture","Capture"
|
11 |
+
"Comment added!","Comment added!"
|
12 |
+
"Add button","Add button"
|
13 |
+
"Button name","Button name"
|
14 |
+
"Delete instance of this module from %s folder","Delete instance of this module from %s folder"
|
15 |
+
"Folder %s deleted!","Folder %s deleted!"
|
16 |
+
"Folder %s delete failed!","Folder %s delete failed!"
|
17 |
+
"Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?","Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?"
|
18 |
+
"Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>","Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>"
|
19 |
+
"http://en.e-abi.ee/magento/better-order-management.html","http://en.e-abi.ee/magento/better-order-management.html"
|
app/locale/et_EE/Eabi_Livehandler.csv
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Enabled","Lubatud"
|
2 |
+
"Global Livehandler settings","Üleüldised seadistused"
|
3 |
+
"Eabi Livehandler","Eabi Livehandler"
|
4 |
+
"Show order info","Näita tellimust"
|
5 |
+
"Invalid action","Viga tellimuse töötlemisel"
|
6 |
+
"Not applicable","Pole saadaval"
|
7 |
+
"Email Invoice","Arve e-postile"
|
8 |
+
"Admin Order Grid Helper","Tellimuste nimekirja moodul"
|
9 |
+
"Open Order in new window when clicking on Order status","Ava tellimus uues aknas kui klikid Tellimuse oleku peale"
|
10 |
+
"Capture","Makstud!"
|
11 |
+
"Comment added!","Kommentaar lisatud!"
|
12 |
+
"Add button","Lisa nupp"
|
13 |
+
"Button name","Nupu nimetus"
|
14 |
+
"Delete instance of this module from %s folder","Kustuta käesoleva mooduli instants %s kaustast"
|
15 |
+
"Folder %s deleted!","Kaust %s kustutatud!"
|
16 |
+
"Folder %s delete failed!","Kausta %s ei õnnestunud kustutada!"
|
17 |
+
"Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?","Tõenäoliselt on vanem versioon käesolevast moodulist Teie süsteemis. Kas soovite selle kustutada %s kaustast?"
|
18 |
+
"Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>","Halda tellimust <a href='%s' target='_blank'>nupukeste abil</a> siitsamast!"
|
19 |
+
"http://en.e-abi.ee/magento/better-order-management.html","http://www.e-abi.ee/magento/better-order-management.html"
|
app/locale/fi_FI/Eabi_Livehandler.csv
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Enabled","Enabled"
|
2 |
+
"Global Livehandler settings","Global Livehandler settings"
|
3 |
+
"Eabi Livehandler","Eabi Livehandler"
|
4 |
+
"Show order info","Show order info"
|
5 |
+
"Invalid action","Invalid action"
|
6 |
+
"Not applicable","Not applicable"
|
7 |
+
"Email Invoice","Email Invoice"
|
8 |
+
"Admin Order Grid Helper","Admin Order Grid Helper"
|
9 |
+
"Open Order in new window when clicking on Order status","Open Order in new window when clicking on Order status"
|
10 |
+
"Capture","Capture"
|
11 |
+
"Comment added!","Comment added!"
|
12 |
+
"Add button","Add button"
|
13 |
+
"Button name","Button name"
|
14 |
+
"Delete instance of this module from %s folder","Delete instance of this module from %s folder"
|
15 |
+
"Folder %s deleted!","Folder %s deleted!"
|
16 |
+
"Folder %s delete failed!","Folder %s delete failed!"
|
17 |
+
"Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?","Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?"
|
18 |
+
"Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>","Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>"
|
19 |
+
"http://en.e-abi.ee/magento/better-order-management.html","http://en.e-abi.ee/magento/better-order-management.html"
|
app/locale/lt_LT/Eabi_Livehandler.csv
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Enabled","Enabled"
|
2 |
+
"Global Livehandler settings","Global Livehandler settings"
|
3 |
+
"Eabi Livehandler","Eabi Livehandler"
|
4 |
+
"Show order info","Show order info"
|
5 |
+
"Invalid action","Invalid action"
|
6 |
+
"Not applicable","Not applicable"
|
7 |
+
"Email Invoice","Email Invoice"
|
8 |
+
"Admin Order Grid Helper","Admin Order Grid Helper"
|
9 |
+
"Open Order in new window when clicking on Order status","Open Order in new window when clicking on Order status"
|
10 |
+
"Capture","Capture"
|
11 |
+
"Comment added!","Comment added!"
|
12 |
+
"Add button","Add button"
|
13 |
+
"Button name","Button name"
|
14 |
+
"Delete instance of this module from %s folder","Delete instance of this module from %s folder"
|
15 |
+
"Folder %s deleted!","Folder %s deleted!"
|
16 |
+
"Folder %s delete failed!","Folder %s delete failed!"
|
17 |
+
"Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?","Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?"
|
18 |
+
"Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>","Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>"
|
19 |
+
"http://en.e-abi.ee/magento/better-order-management.html","http://en.e-abi.ee/magento/better-order-management.html"
|
app/locale/sv_SE/Eabi_Livehandler.csv
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Enabled","Enabled"
|
2 |
+
"Global Livehandler settings","Global Livehandler settings"
|
3 |
+
"Eabi Livehandler","Eabi Livehandler"
|
4 |
+
"Show order info","Show order info"
|
5 |
+
"Invalid action","Invalid action"
|
6 |
+
"Not applicable","Not applicable"
|
7 |
+
"Email Invoice","Email Invoice"
|
8 |
+
"Admin Order Grid Helper","Admin Order Grid Helper"
|
9 |
+
"Open Order in new window when clicking on Order status","Open Order in new window when clicking on Order status"
|
10 |
+
"Capture","Capture"
|
11 |
+
"Comment added!","Comment added!"
|
12 |
+
"Add button","Add button"
|
13 |
+
"Button name","Button name"
|
14 |
+
"Delete instance of this module from %s folder","Delete instance of this module from %s folder"
|
15 |
+
"Folder %s deleted!","Folder %s deleted!"
|
16 |
+
"Folder %s delete failed!","Folder %s delete failed!"
|
17 |
+
"Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?","Most probably you have older version of this module in the system. Do you want to remove the instance of this module from %s folder?"
|
18 |
+
"Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>","Manage the order from here by adding <a href='%s' target='_blank'>action buttons</a>"
|
19 |
+
"http://en.e-abi.ee/magento/better-order-management.html","http://en.e-abi.ee/magento/better-order-management.html"
|
js/eabi_js/crossBrowser_initKeyboardEvent.js
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Podium = {};
|
3 |
+
Podium.keydown = function(k) {
|
4 |
+
var oEvent = document.createEvent('KeyboardEvent');
|
5 |
+
|
6 |
+
// Chromium Hack
|
7 |
+
Object.defineProperty(oEvent, 'keyCode', {
|
8 |
+
get : function() {
|
9 |
+
return this.keyCodeVal;
|
10 |
+
}
|
11 |
+
});
|
12 |
+
Object.defineProperty(oEvent, 'which', {
|
13 |
+
get : function() {
|
14 |
+
return this.keyCodeVal;
|
15 |
+
}
|
16 |
+
});
|
17 |
+
|
18 |
+
if (oEvent.initKeyboardEvent) {
|
19 |
+
oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, false, false, false, false, k, k);
|
20 |
+
} else {
|
21 |
+
oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, k, 0);
|
22 |
+
}
|
23 |
+
|
24 |
+
oEvent.keyCodeVal = k;
|
25 |
+
|
26 |
+
if (oEvent.keyCode !== k) {
|
27 |
+
alert("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ")");
|
28 |
+
}
|
29 |
+
|
30 |
+
document.dispatchEvent(oEvent);
|
31 |
+
}
|
js/livepipe/contextmenu.js
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/contextmenu
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global window, document, Prototype, Class, Event, $, $A, $R, Control, $value */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.ContextMenu requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.ContextMenu requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.ContextMenu = Class.create({
|
18 |
+
initialize: function(container,options){
|
19 |
+
Control.ContextMenu.load();
|
20 |
+
this.options = Object.extend({
|
21 |
+
leftClick: false,
|
22 |
+
disableOnShiftKey: true,
|
23 |
+
disableOnAltKey: true,
|
24 |
+
selectedClassName: 'selected',
|
25 |
+
activatedClassName: 'activated',
|
26 |
+
animation: true,
|
27 |
+
animationCycles: 2,
|
28 |
+
animationLength: 300,
|
29 |
+
delayCallback: true
|
30 |
+
},options || {});
|
31 |
+
this.activated = false;
|
32 |
+
this.items = this.options.items || [];
|
33 |
+
this.container = $(container);
|
34 |
+
this.container.observe(this.options.leftClick ? 'click' : (Prototype.Browser.Opera ? 'click' : 'contextmenu'),function(event){
|
35 |
+
if(!Control.ContextMenu.enabled || Prototype.Browser.Opera && !event.ctrlKey) {
|
36 |
+
return; }
|
37 |
+
this.open(event);
|
38 |
+
}.bindAsEventListener(this));
|
39 |
+
},
|
40 |
+
open: function(event){
|
41 |
+
if(Control.ContextMenu.current && !Control.ContextMenu.current.close()) {
|
42 |
+
return; }
|
43 |
+
if(this.notify('beforeOpen',event) === false) {
|
44 |
+
return false; }
|
45 |
+
this.buildMenu();
|
46 |
+
if(this.items.length === 0){
|
47 |
+
this.close(event);
|
48 |
+
return false;
|
49 |
+
}
|
50 |
+
this.clicked = Event.element(event);
|
51 |
+
Control.ContextMenu.current = this;
|
52 |
+
Control.ContextMenu.positionContainer(event);
|
53 |
+
Control.ContextMenu.container.show();
|
54 |
+
if(this.notify('afterOpen',event) === false) {
|
55 |
+
return false; }
|
56 |
+
event.stop();
|
57 |
+
return true;
|
58 |
+
},
|
59 |
+
close: function(event){
|
60 |
+
if(event) {
|
61 |
+
event.stop(); }
|
62 |
+
if(this.notify('beforeClose') === false) {
|
63 |
+
return false; }
|
64 |
+
Control.ContextMenu.current = false;
|
65 |
+
this.activated = false;
|
66 |
+
Control.ContextMenu.container.removeClassName(this.options.activatedClassName);
|
67 |
+
Control.ContextMenu.container.select('li').invoke('stopObserving');
|
68 |
+
Control.ContextMenu.container.hide();
|
69 |
+
Control.ContextMenu.container.update('');
|
70 |
+
if(this.notify('afterClose') === false) {
|
71 |
+
return false; }
|
72 |
+
return true;
|
73 |
+
},
|
74 |
+
buildMenu: function(){
|
75 |
+
var list = document.createElement('ul');
|
76 |
+
Control.ContextMenu.container.appendChild(list);
|
77 |
+
this.items.each(function(item){
|
78 |
+
if(!(!item.condition || item.condition && item.condition() !== false)) {
|
79 |
+
return; }
|
80 |
+
var item_container = $(document.createElement('li'));
|
81 |
+
item_container.update($value(item.label));
|
82 |
+
list.appendChild(item_container);
|
83 |
+
item_container[$value(item.enabled) ? 'removeClassName' : 'addClassName']('disabled');
|
84 |
+
item_container.observe('mousedown',function(event,item){
|
85 |
+
if(!$value(item.enabled)) {
|
86 |
+
return event.stop(); }
|
87 |
+
this.activated = $value(item.label);
|
88 |
+
}.bindAsEventListener(this,item));
|
89 |
+
item_container.observe('click',this.selectMenuItem.bindAsEventListener(this,item,item_container));
|
90 |
+
item_container.observe('contextmenu',this.selectMenuItem.bindAsEventListener(this,item,item_container));
|
91 |
+
}.bind(this));
|
92 |
+
},
|
93 |
+
addItem: function(params){
|
94 |
+
if (!('enabled' in params)) { params.enabled = true; }
|
95 |
+
this.items.push(params);
|
96 |
+
return this;
|
97 |
+
},
|
98 |
+
destroy: function(){
|
99 |
+
this.container.stopObserving(Prototype.Browser.Opera || this.options.leftClick ? 'click' : 'contextmenu');
|
100 |
+
this.items = [];
|
101 |
+
},
|
102 |
+
selectMenuItem: function(event,item,item_container){
|
103 |
+
if(!$value(item.enabled)) {
|
104 |
+
return event.stop(); }
|
105 |
+
if(!this.activated || this.activated == $value(item.label)){
|
106 |
+
if(this.options.animation){
|
107 |
+
Control.ContextMenu.container.addClassName(this.options.activatedClassName);
|
108 |
+
$A($R(0,this.options.animationCycles * 2)).each(function(i){
|
109 |
+
window.setTimeout(function(){
|
110 |
+
item_container.toggleClassName(this.options.selectedClassName);
|
111 |
+
}.bind(this),i * parseInt(this.options.animationLength / (this.options.animationCycles * 2), 10));
|
112 |
+
}.bind(this));
|
113 |
+
window.setTimeout(function(){
|
114 |
+
if(this.close() && this.options.delayCallback) {
|
115 |
+
item.callback(this.clicked); }
|
116 |
+
}.bind(this),this.options.animationLength);
|
117 |
+
if(!this.options.delayCallback) {
|
118 |
+
item.callback(this.clicked); }
|
119 |
+
}else if(this.close()) {
|
120 |
+
item.callback(this.clicked); }
|
121 |
+
}
|
122 |
+
event.stop();
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
});
|
126 |
+
Object.extend(Control.ContextMenu,{
|
127 |
+
loaded: false,
|
128 |
+
capture_all: false,
|
129 |
+
menus: [],
|
130 |
+
current: false,
|
131 |
+
enabled: false,
|
132 |
+
offset: 4,
|
133 |
+
load: function(capture_all){
|
134 |
+
if(Control.ContextMenu.loaded) {
|
135 |
+
return; }
|
136 |
+
Control.ContextMenu.loaded = true;
|
137 |
+
if(typeof(capture_all) == 'undefined') {
|
138 |
+
capture_all = false; }
|
139 |
+
Control.ContextMenu.capture_all = capture_all;
|
140 |
+
Control.ContextMenu.container = $(document.createElement('div'));
|
141 |
+
Control.ContextMenu.container.id = 'control_contextmenu';
|
142 |
+
Control.ContextMenu.container.style.position = 'absolute';
|
143 |
+
Control.ContextMenu.container.style.zIndex = 99999;
|
144 |
+
Control.ContextMenu.container.hide();
|
145 |
+
document.body.appendChild(Control.ContextMenu.container);
|
146 |
+
Control.ContextMenu.enable();
|
147 |
+
},
|
148 |
+
enable: function(){
|
149 |
+
Control.ContextMenu.enabled = true;
|
150 |
+
Event.observe(document.body,'click',Control.ContextMenu.onClick);
|
151 |
+
if(Control.ContextMenu.capture_all) {
|
152 |
+
Event.observe(document.body,'contextmenu',Control.ContextMenu.onContextMenu); }
|
153 |
+
},
|
154 |
+
disable: function(){
|
155 |
+
Event.stopObserving(document.body,'click',Control.ContextMenu.onClick);
|
156 |
+
if(Control.ContextMenu.capture_all) {
|
157 |
+
Event.stopObserving(document.body,'contextmenu',Control.ContextMenu.onContextMenu); }
|
158 |
+
},
|
159 |
+
onContextMenu: function(event){
|
160 |
+
event.stop();
|
161 |
+
return false;
|
162 |
+
},
|
163 |
+
onClick: function(){
|
164 |
+
if(Control.ContextMenu.current) {
|
165 |
+
Control.ContextMenu.current.close(); }
|
166 |
+
},
|
167 |
+
positionContainer: function(event){
|
168 |
+
var dimensions = Control.ContextMenu.container.getDimensions();
|
169 |
+
var top = Event.pointerY(event);
|
170 |
+
var left = Event.pointerX(event);
|
171 |
+
var bottom = dimensions.height + top;
|
172 |
+
var right = dimensions.width + left;
|
173 |
+
var viewport_dimensions = document.viewport.getDimensions();
|
174 |
+
var viewport_scroll_offsets = document.viewport.getScrollOffsets();
|
175 |
+
if(bottom > viewport_dimensions.height + viewport_scroll_offsets.top) {
|
176 |
+
top -= bottom - ((viewport_dimensions.height + viewport_scroll_offsets.top) - Control.ContextMenu.offset); }
|
177 |
+
if(right > viewport_dimensions.width + viewport_scroll_offsets.left) {
|
178 |
+
left -= right - ((viewport_dimensions.width + viewport_scroll_offsets.left) - Control.ContextMenu.offset); }
|
179 |
+
Control.ContextMenu.container.setStyle({
|
180 |
+
top: top + 'px',
|
181 |
+
left: left + 'px'
|
182 |
+
});
|
183 |
+
}
|
184 |
+
});
|
185 |
+
Object.Event.extend(Control.ContextMenu);
|
js/livepipe/cookie.js
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/controls/hotkey/
|
7 |
+
* @attribution http://www.quirksmode.org/js/cookies.html
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global document, Prototype, $A */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Cookie requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Cookie requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
var Cookie = {
|
18 |
+
build: function() {
|
19 |
+
return $A(arguments).compact().join("; ");
|
20 |
+
},
|
21 |
+
secondsFromNow: function(seconds) {
|
22 |
+
var d = new Date();
|
23 |
+
d.setTime(d.getTime() + (seconds * 1000));
|
24 |
+
return d.toGMTString();
|
25 |
+
},
|
26 |
+
set: function(name,value,seconds){
|
27 |
+
Cookie.notify('set',name,value);
|
28 |
+
var expiry = seconds ? 'expires=' + Cookie.secondsFromNow(seconds) : null;
|
29 |
+
document.cookie = Cookie.build(name + "=" + value, expiry, "path=/");
|
30 |
+
},
|
31 |
+
get: function(name){
|
32 |
+
Cookie.notify('get',name);
|
33 |
+
var valueMatch = new RegExp(name + "=([^;]+)").exec(document.cookie);
|
34 |
+
return valueMatch ? valueMatch[1] : null;
|
35 |
+
},
|
36 |
+
unset: function(name){
|
37 |
+
Cookie.notify('unset',name);
|
38 |
+
Cookie.set(name,'',-1);
|
39 |
+
}
|
40 |
+
};
|
41 |
+
Object.Event.extend(Cookie);
|
js/livepipe/event_behavior.js
ADDED
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/extra/event_behavior
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
* @attribution http://www.adamlogic.com/2007/03/20/3_metaprogramming-javascript-presentation
|
9 |
+
*/
|
10 |
+
|
11 |
+
/*global Prototype, Class, Event, Try, $, $A, $H */
|
12 |
+
|
13 |
+
if(typeof(Prototype) == "undefined") {
|
14 |
+
throw "Event.Behavior requires Prototype to be loaded."; }
|
15 |
+
if(typeof(Object.Event) == "undefined") {
|
16 |
+
throw "Event.Behavior requires Object.Event to be loaded."; }
|
17 |
+
|
18 |
+
Event.Behavior = {
|
19 |
+
addVerbs: function(verbs){
|
20 |
+
var v;
|
21 |
+
for (var name in verbs) { if (verbs.hasOwnProperty(name)) {
|
22 |
+
v = new Event.Behavior.Verb(verbs[name]);
|
23 |
+
Event.Behavior.Verbs[name] = v;
|
24 |
+
Event.Behavior[name.underscore()] = Event.Behavior[name] = v.getCallbackForStack.bind(v);
|
25 |
+
}}
|
26 |
+
},
|
27 |
+
addEvents: function(events){
|
28 |
+
$H(events).each(function(event_type){
|
29 |
+
Event.Behavior.Adjective.prototype[event_type.key.underscore()] = Event.Behavior.Adjective.prototype[event_type.key] = function(){
|
30 |
+
this.nextConditionType = 'and';
|
31 |
+
this.events.push(event_type.value);
|
32 |
+
this.attachObserver(false);
|
33 |
+
return this;
|
34 |
+
};
|
35 |
+
});
|
36 |
+
},
|
37 |
+
invokeElementMethod: function(element,action,args){
|
38 |
+
if(typeof(element) == 'function'){
|
39 |
+
return $A(element()).each(function(e){
|
40 |
+
if(typeof(args[0]) == 'function'){
|
41 |
+
return $A(args[0]).each(function(a){
|
42 |
+
return $(e)[action].apply($(e),(a ? [a] : []));
|
43 |
+
});
|
44 |
+
}else {
|
45 |
+
return $(e)[action].apply($(e),args || []); }
|
46 |
+
});
|
47 |
+
}else {
|
48 |
+
return $(element)[action].apply($(element),args || []); }
|
49 |
+
}
|
50 |
+
};
|
51 |
+
|
52 |
+
Event.Behavior.Verbs = $H({});
|
53 |
+
|
54 |
+
Event.Behavior.Verb = Class.create();
|
55 |
+
Object.extend(Event.Behavior.Verb.prototype,{
|
56 |
+
originalAction: false,
|
57 |
+
execute: false,
|
58 |
+
executeOpposite: false,
|
59 |
+
target: false,
|
60 |
+
initialize: function(action){
|
61 |
+
this.originalAction = action;
|
62 |
+
this.execute = function(action,target,argument){
|
63 |
+
return (argument) ? action(target,argument) : action(target);
|
64 |
+
}.bind(this,action);
|
65 |
+
},
|
66 |
+
setOpposite: function(opposite_verb){
|
67 |
+
var opposite_action = opposite_verb.originalAction;
|
68 |
+
this.executeOpposite = function(opposite_action,target,argument){
|
69 |
+
return (argument) ? opposite_action(target,argument) :
|
70 |
+
opposite_action(target);
|
71 |
+
}.bind(this,opposite_action);
|
72 |
+
},
|
73 |
+
getCallbackForStack: function(argument){
|
74 |
+
return new Event.Behavior.Noun(this,argument);
|
75 |
+
}
|
76 |
+
});
|
77 |
+
|
78 |
+
Event.Behavior.addVerbs({
|
79 |
+
call: function(callback){
|
80 |
+
callback();
|
81 |
+
},
|
82 |
+
show: function(element){
|
83 |
+
return Event.Behavior.invokeElementMethod(element,'show');
|
84 |
+
},
|
85 |
+
hide: function(element){
|
86 |
+
return Event.Behavior.invokeElementMethod(element,'hide');
|
87 |
+
},
|
88 |
+
remove: function(element){
|
89 |
+
return Event.Behavior.invokeElementMethod(element,'remove');
|
90 |
+
},
|
91 |
+
setStyle: function(element,styles){
|
92 |
+
return Event.Behavior.invokeElementMethod(element,'setStyle',[(typeof(styles) == 'function' ? styles() : styles)]);
|
93 |
+
},
|
94 |
+
addClassName: function(element,class_name){
|
95 |
+
return Event.Behavior.invokeElementMethod(element,'addClassName',[(typeof(class_name) == 'function' ? class_name() : class_name)]);
|
96 |
+
},
|
97 |
+
removeClassName: function(element,class_name){
|
98 |
+
return Event.Behavior.invokeElementMethod(element,'removeClassName',[(typeof(class_name) == 'function' ? class_name() : class_name)]);
|
99 |
+
},
|
100 |
+
setClassName: function(element,class_name){
|
101 |
+
var c = (typeof(class_name) == 'function') ? class_name() : class_name;
|
102 |
+
if(typeof(element) == 'function'){
|
103 |
+
return $A(element()).each(function(e){
|
104 |
+
$(e).className = c;
|
105 |
+
});
|
106 |
+
}else {
|
107 |
+
c = $(element).className;
|
108 |
+
return c;
|
109 |
+
}
|
110 |
+
},
|
111 |
+
update: function(content,element){
|
112 |
+
return Event.Behavior.invokeElementMethod(element,'update',[(typeof(content) == 'function' ? content() : content)]);
|
113 |
+
},
|
114 |
+
replace: function(content,element){
|
115 |
+
return Event.Behavior.invokeElementMethod(element,'replace',[(typeof(content) == 'function' ? content() : content)]);
|
116 |
+
}
|
117 |
+
});
|
118 |
+
Event.Behavior.Verbs.show.setOpposite(Event.Behavior.Verbs.hide);
|
119 |
+
Event.Behavior.Verbs.hide.setOpposite(Event.Behavior.Verbs.show);
|
120 |
+
Event.Behavior.Verbs.addClassName.setOpposite(Event.Behavior.Verbs.removeClassName);
|
121 |
+
Event.Behavior.Verbs.removeClassName.setOpposite(Event.Behavior.Verbs.addClassName);
|
122 |
+
|
123 |
+
Event.Behavior.Noun = Class.create();
|
124 |
+
Object.extend(Event.Behavior.Noun.prototype,{
|
125 |
+
verbs: false,
|
126 |
+
verb: false,
|
127 |
+
argument: false,
|
128 |
+
subject: false,
|
129 |
+
target: false,
|
130 |
+
initialize: function(verb,argument){
|
131 |
+
//this.verbs = $A([]);
|
132 |
+
this.verb = verb;
|
133 |
+
this.argument = argument;
|
134 |
+
},
|
135 |
+
execute: function(){
|
136 |
+
return (this.target) ? this.verb.execute(this.target,this.argument) :
|
137 |
+
this.verb.execute(this.argument);
|
138 |
+
},
|
139 |
+
executeOpposite: function(){
|
140 |
+
return (this.target) ?
|
141 |
+
this.verb.executeOpposite(this.target,this.argument) :
|
142 |
+
this.verb.executeOpposite(this.argument);
|
143 |
+
},
|
144 |
+
when: function(subject){
|
145 |
+
this.subject = subject;
|
146 |
+
return new Event.Behavior.Adjective(this);
|
147 |
+
},
|
148 |
+
getValue: function(){
|
149 |
+
return Try.these(
|
150 |
+
function(){return $(this.subject).getValue();}.bind(this),
|
151 |
+
function(){return $(this.subject).options[$(this.subject).options.selectedIndex].value;}.bind(this),
|
152 |
+
function(){return $(this.subject).value;}.bind(this),
|
153 |
+
function(){return $(this.subject).innerHTML;}.bind(this)
|
154 |
+
);
|
155 |
+
},
|
156 |
+
containsValue: function(match){
|
157 |
+
var value = this.getValue();
|
158 |
+
if(typeof(match) == 'function'){
|
159 |
+
return $A(match()).include(value);
|
160 |
+
}else {
|
161 |
+
return value.match(match); }
|
162 |
+
},
|
163 |
+
setTarget: function(target){
|
164 |
+
this.target = target;
|
165 |
+
return this;
|
166 |
+
},
|
167 |
+
and: function(){
|
168 |
+
|
169 |
+
}
|
170 |
+
});
|
171 |
+
Event.Behavior.Noun.prototype._with = Event.Behavior.Noun.prototype.setTarget;
|
172 |
+
Event.Behavior.Noun.prototype.on = Event.Behavior.Noun.prototype.setTarget;
|
173 |
+
Event.Behavior.Noun.prototype.of = Event.Behavior.Noun.prototype.setTarget;
|
174 |
+
Event.Behavior.Noun.prototype.to = Event.Behavior.Noun.prototype.setTarget;
|
175 |
+
Event.Behavior.Noun.prototype.from = Event.Behavior.Noun.prototype.setTarget;
|
176 |
+
|
177 |
+
Event.Behavior.Adjective = Class.create();
|
178 |
+
Object.extend(Event.Behavior.Adjective.prototype,{
|
179 |
+
noun: false,
|
180 |
+
lastConditionName: '',
|
181 |
+
nextConditionType: 'and',
|
182 |
+
conditions: $A([]),
|
183 |
+
events: $A([]),
|
184 |
+
attached: false,
|
185 |
+
initialize: function(noun){
|
186 |
+
this.conditions = $A([]);
|
187 |
+
this.events = $A([]);
|
188 |
+
this.noun = noun;
|
189 |
+
},
|
190 |
+
attachObserver: function(execute_on_load){
|
191 |
+
if(this.attached){
|
192 |
+
//this may call things multiple times, but is the only way to gaurentee correct state on startup
|
193 |
+
if(execute_on_load) {
|
194 |
+
this.execute(); }
|
195 |
+
return;
|
196 |
+
}
|
197 |
+
this.attached = true;
|
198 |
+
if(typeof(this.noun.subject) == 'function'){
|
199 |
+
$A(this.noun.subject()).each(function(subject){
|
200 |
+
(this.events.length > 0 ? this.events : $A(['change'])).each(function(event_name){
|
201 |
+
(subject.observe ? subject : $(subject)).observe(event_name,function(){
|
202 |
+
this.execute();
|
203 |
+
}.bind(this));
|
204 |
+
}.bind(this));
|
205 |
+
}.bind(this));
|
206 |
+
}else{
|
207 |
+
(this.events.length > 0 ? this.events : $A(['change'])).each(function(event_name){
|
208 |
+
$(this.noun.subject).observe(event_name,function(){
|
209 |
+
this.execute();
|
210 |
+
}.bind(this));
|
211 |
+
}.bind(this));
|
212 |
+
}
|
213 |
+
if(execute_on_load) { this.execute(); }
|
214 |
+
},
|
215 |
+
execute: function(){
|
216 |
+
if(this.match()) { return this.noun.execute(); }
|
217 |
+
else if(this.noun.verb.executeOpposite) { this.noun.executeOpposite(); }
|
218 |
+
},
|
219 |
+
attachCondition: function(callback){
|
220 |
+
this.conditions.push([this.nextConditionType,callback.bind(this)]);
|
221 |
+
},
|
222 |
+
match: function(){
|
223 |
+
if(this.conditions.length === 0) { return true; }
|
224 |
+
else {
|
225 |
+
return this.conditions.inject(false, function (bool,condition) {
|
226 |
+
return (condition[0] === 'or') ?
|
227 |
+
(bool && condition[1]()) : (bool || condition[1]());
|
228 |
+
});
|
229 |
+
}
|
230 |
+
},
|
231 |
+
//conditions
|
232 |
+
is: function(item){
|
233 |
+
this.lastConditionName = 'is';
|
234 |
+
this.attachCondition(function(item){
|
235 |
+
return (typeof(item) == 'function' ? item() : item) == this.noun.getValue();
|
236 |
+
}.bind(this,item));
|
237 |
+
this.attachObserver(true);
|
238 |
+
return this;
|
239 |
+
},
|
240 |
+
isNot: function(item){
|
241 |
+
this.lastConditionName = 'isNot';
|
242 |
+
this.attachCondition(function(item){
|
243 |
+
return (typeof(item) == 'function' ? item() : item) != this.noun.getValue();
|
244 |
+
}.bind(this,item));
|
245 |
+
this.attachObserver(true);
|
246 |
+
return this;
|
247 |
+
},
|
248 |
+
contains: function(item){
|
249 |
+
this.lastConditionName = 'contains';
|
250 |
+
this.attachCondition(function(item){
|
251 |
+
return this.noun.containsValue(item);
|
252 |
+
}.bind(this,item));
|
253 |
+
this.attachObserver(true);
|
254 |
+
return this;
|
255 |
+
},
|
256 |
+
within: function(item){
|
257 |
+
this.lastConditionName = 'within';
|
258 |
+
this.attachCondition(function(item){
|
259 |
+
|
260 |
+
}.bind(this,item));
|
261 |
+
this.attachObserver(true);
|
262 |
+
return this;
|
263 |
+
},
|
264 |
+
//events
|
265 |
+
change: function(){
|
266 |
+
this.nextConditionType = 'and';
|
267 |
+
this.attachObserver(true);
|
268 |
+
return this;
|
269 |
+
},
|
270 |
+
and: function(condition){
|
271 |
+
this.attached = false;
|
272 |
+
this.nextConditionType = 'and';
|
273 |
+
if(condition) { this[this.lastConditionName](condition); }
|
274 |
+
return this;
|
275 |
+
},
|
276 |
+
or: function(condition){
|
277 |
+
this.attached = false;
|
278 |
+
this.nextConditionType = 'or';
|
279 |
+
if(condition) { this[this.lastConditionName](condition); }
|
280 |
+
return this;
|
281 |
+
}
|
282 |
+
});
|
283 |
+
|
284 |
+
Event.Behavior.addEvents({
|
285 |
+
losesFocus: 'blur',
|
286 |
+
gainsFocus: 'focus',
|
287 |
+
isClicked: 'click',
|
288 |
+
isDoubleClicked: 'dblclick',
|
289 |
+
keyPressed: 'keypress'
|
290 |
+
});
|
291 |
+
|
292 |
+
Event.Behavior.Adjective.prototype.is_not = Event.Behavior.Adjective.prototype.isNot;
|
293 |
+
Event.Behavior.Adjective.prototype.include = Event.Behavior.Adjective.prototype.contains;
|
294 |
+
Event.Behavior.Adjective.prototype.includes = Event.Behavior.Adjective.prototype.contains;
|
295 |
+
Event.Behavior.Adjective.prototype.are = Event.Behavior.Adjective.prototype.is;
|
296 |
+
Event.Behavior.Adjective.prototype.areNot = Event.Behavior.Adjective.prototype.isNot;
|
297 |
+
Event.Behavior.Adjective.prototype.are_not = Event.Behavior.Adjective.prototype.isNot;
|
298 |
+
Event.Behavior.Adjective.prototype.changes = Event.Behavior.Adjective.prototype.change;
|
js/livepipe/hotkey.js
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/extra/hotkey
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global document, Prototype, Class, Event, $ */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "HotKey requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "HotKey requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
var HotKey = Class.create({
|
18 |
+
initialize: function(letter,callback,options){
|
19 |
+
letter = letter.toUpperCase();
|
20 |
+
HotKey.hotkeys.push(this);
|
21 |
+
this.options = Object.extend({
|
22 |
+
element: false,
|
23 |
+
shiftKey: false,
|
24 |
+
altKey: false,
|
25 |
+
ctrlKey: true,
|
26 |
+
bubbleEvent : true,
|
27 |
+
fireOnce : false // Keep repeating event while key is pressed?
|
28 |
+
},options || {});
|
29 |
+
this.letter = letter;
|
30 |
+
|
31 |
+
// All custom hotkey events should stop after their custom actions.
|
32 |
+
this.callback = function (event) {
|
33 |
+
if (!(this.options.fireOnce && this.fired) && Object.isFunction(callback)) {
|
34 |
+
callback(event);
|
35 |
+
}
|
36 |
+
if (!this.options.bubbleEvent) { event.stop(); }
|
37 |
+
this.fired = true;
|
38 |
+
};
|
39 |
+
|
40 |
+
this.element = $(this.options.element || document);
|
41 |
+
this.handler = function(event){
|
42 |
+
if(!event || (
|
43 |
+
(Event['KEY_' + this.letter] || this.letter.charCodeAt(0)) == event.keyCode &&
|
44 |
+
((!this.options.shiftKey || (this.options.shiftKey && event.shiftKey)) &&
|
45 |
+
(!this.options.altKey || (this.options.altKey && event.altKey)) &&
|
46 |
+
(!this.options.ctrlKey || (this.options.ctrlKey && event.ctrlKey))
|
47 |
+
)
|
48 |
+
)){
|
49 |
+
if(this.notify('beforeCallback',event) === false) {
|
50 |
+
return; }
|
51 |
+
this.callback(event);
|
52 |
+
this.notify('afterCallback',event);
|
53 |
+
}
|
54 |
+
}.bind(this);
|
55 |
+
this.enable();
|
56 |
+
},
|
57 |
+
trigger: function(){
|
58 |
+
this.handler();
|
59 |
+
},
|
60 |
+
enable: function(){
|
61 |
+
this.element.observe('keydown',this.handler);
|
62 |
+
},
|
63 |
+
disable: function(){
|
64 |
+
this.element.stopObserving('keydown',this.handler);
|
65 |
+
},
|
66 |
+
destroy: function(){
|
67 |
+
this.disable();
|
68 |
+
HotKey.hotkeys = HotKey.hotkeys.without(this);
|
69 |
+
}
|
70 |
+
});
|
71 |
+
Object.extend(HotKey,{
|
72 |
+
hotkeys: []
|
73 |
+
});
|
74 |
+
Object.Event.extend(HotKey);
|
js/livepipe/livepipe.js
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/core
|
7 |
+
* @require prototype.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
if(typeof(Control) == 'undefined')
|
11 |
+
Control = {};
|
12 |
+
|
13 |
+
var $proc = function(proc){
|
14 |
+
return typeof(proc) == 'function' ? proc : function(){return proc};
|
15 |
+
};
|
16 |
+
|
17 |
+
var $value = function(value){
|
18 |
+
return typeof(value) == 'function' ? value() : value;
|
19 |
+
};
|
20 |
+
|
21 |
+
Object.Event = {
|
22 |
+
extend: function(object){
|
23 |
+
object._objectEventSetup = function(event_name){
|
24 |
+
this._observers = this._observers || {};
|
25 |
+
this._observers[event_name] = this._observers[event_name] || [];
|
26 |
+
};
|
27 |
+
object.observe = function(event_name,observer){
|
28 |
+
if(typeof(event_name) == 'string' && typeof(observer) != 'undefined'){
|
29 |
+
this._objectEventSetup(event_name);
|
30 |
+
if(!this._observers[event_name].include(observer))
|
31 |
+
this._observers[event_name].push(observer);
|
32 |
+
}else
|
33 |
+
for(var e in event_name)
|
34 |
+
this.observe(e,event_name[e]);
|
35 |
+
};
|
36 |
+
object.stopObserving = function(event_name,observer){
|
37 |
+
this._objectEventSetup(event_name);
|
38 |
+
if(event_name && observer)
|
39 |
+
this._observers[event_name] = this._observers[event_name].without(observer);
|
40 |
+
else if(event_name)
|
41 |
+
this._observers[event_name] = [];
|
42 |
+
else
|
43 |
+
this._observers = {};
|
44 |
+
};
|
45 |
+
object.observeOnce = function(event_name,outer_observer){
|
46 |
+
var inner_observer = function(){
|
47 |
+
outer_observer.apply(this,arguments);
|
48 |
+
this.stopObserving(event_name,inner_observer);
|
49 |
+
}.bind(this);
|
50 |
+
this._objectEventSetup(event_name);
|
51 |
+
this._observers[event_name].push(inner_observer);
|
52 |
+
};
|
53 |
+
object.notify = function(event_name){
|
54 |
+
this._objectEventSetup(event_name);
|
55 |
+
var collected_return_values = [];
|
56 |
+
var args = $A(arguments).slice(1);
|
57 |
+
try{
|
58 |
+
for(var i = 0; i < this._observers[event_name].length; ++i)
|
59 |
+
collected_return_values.push(this._observers[event_name][i].apply(this,args) || null);
|
60 |
+
}catch(e){
|
61 |
+
if(e == $break)
|
62 |
+
return false;
|
63 |
+
else
|
64 |
+
throw e;
|
65 |
+
}
|
66 |
+
return collected_return_values;
|
67 |
+
};
|
68 |
+
if(object.prototype){
|
69 |
+
object.prototype._objectEventSetup = object._objectEventSetup;
|
70 |
+
object.prototype.observe = object.observe;
|
71 |
+
object.prototype.stopObserving = object.stopObserving;
|
72 |
+
object.prototype.observeOnce = object.observeOnce;
|
73 |
+
object.prototype.notify = function(event_name){
|
74 |
+
if(object.notify){
|
75 |
+
var args = $A(arguments).slice(1);
|
76 |
+
args.unshift(this);
|
77 |
+
args.unshift(event_name);
|
78 |
+
object.notify.apply(object,args);
|
79 |
+
}
|
80 |
+
this._objectEventSetup(event_name);
|
81 |
+
var args = $A(arguments).slice(1);
|
82 |
+
var collected_return_values = [];
|
83 |
+
try{
|
84 |
+
if(this.options && this.options[event_name] && typeof(this.options[event_name]) == 'function')
|
85 |
+
collected_return_values.push(this.options[event_name].apply(this,args) || null);
|
86 |
+
var callbacks_copy = this._observers[event_name]; // since original array will be modified after observeOnce calls
|
87 |
+
for(var i = 0; i < callbacks_copy.length; ++i)
|
88 |
+
collected_return_values.push(callbacks_copy[i].apply(this,args) || null);
|
89 |
+
}catch(e){
|
90 |
+
if(e == $break)
|
91 |
+
return false;
|
92 |
+
else
|
93 |
+
throw e;
|
94 |
+
}
|
95 |
+
return collected_return_values;
|
96 |
+
};
|
97 |
+
}
|
98 |
+
}
|
99 |
+
};
|
100 |
+
|
101 |
+
/* Begin Core Extensions */
|
102 |
+
|
103 |
+
//Element.observeOnce
|
104 |
+
Element.addMethods({
|
105 |
+
observeOnce: function(element,event_name,outer_callback){
|
106 |
+
var inner_callback = function(){
|
107 |
+
outer_callback.apply(this,arguments);
|
108 |
+
Element.stopObserving(element,event_name,inner_callback);
|
109 |
+
};
|
110 |
+
Element.observe(element,event_name,inner_callback);
|
111 |
+
}
|
112 |
+
});
|
113 |
+
|
114 |
+
//mouse:wheel
|
115 |
+
(function(){
|
116 |
+
function wheel(event){
|
117 |
+
var delta, element, custom_event;
|
118 |
+
// normalize the delta
|
119 |
+
if (event.wheelDelta) { // IE & Opera
|
120 |
+
delta = event.wheelDelta / 120;
|
121 |
+
} else if (event.detail) { // W3C
|
122 |
+
delta =- event.detail / 3;
|
123 |
+
}
|
124 |
+
if (!delta) { return; }
|
125 |
+
element = Event.extend(event).target;
|
126 |
+
element = Element.extend(element.nodeType === Node.TEXT_NODE ? element.parentNode : element);
|
127 |
+
custom_event = element.fire('mouse:wheel',{ delta: delta });
|
128 |
+
if (custom_event.stopped) {
|
129 |
+
Event.stop(event);
|
130 |
+
return false;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
document.observe('mousewheel',wheel);
|
134 |
+
document.observe('DOMMouseScroll',wheel);
|
135 |
+
})();
|
136 |
+
|
137 |
+
/* End Core Extensions */
|
138 |
+
|
139 |
+
//from PrototypeUI
|
140 |
+
var IframeShim = Class.create({
|
141 |
+
initialize: function() {
|
142 |
+
this.element = new Element('iframe',{
|
143 |
+
style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none',
|
144 |
+
src: 'javascript:false;',
|
145 |
+
frameborder: 0
|
146 |
+
});
|
147 |
+
$(document.body).insert(this.element);
|
148 |
+
},
|
149 |
+
hide: function() {
|
150 |
+
this.element.hide();
|
151 |
+
return this;
|
152 |
+
},
|
153 |
+
show: function() {
|
154 |
+
this.element.show();
|
155 |
+
return this;
|
156 |
+
},
|
157 |
+
positionUnder: function(element) {
|
158 |
+
var element = $(element);
|
159 |
+
var offset = element.cumulativeOffset();
|
160 |
+
var dimensions = element.getDimensions();
|
161 |
+
this.element.setStyle({
|
162 |
+
left: offset[0] + 'px',
|
163 |
+
top: offset[1] + 'px',
|
164 |
+
width: dimensions.width + 'px',
|
165 |
+
height: dimensions.height + 'px',
|
166 |
+
zIndex: element.getStyle('zIndex') - 1
|
167 |
+
}).show();
|
168 |
+
return this;
|
169 |
+
},
|
170 |
+
setBounds: function(bounds) {
|
171 |
+
for(prop in bounds)
|
172 |
+
bounds[prop] += 'px';
|
173 |
+
this.element.setStyle(bounds);
|
174 |
+
return this;
|
175 |
+
},
|
176 |
+
destroy: function() {
|
177 |
+
if(this.element)
|
178 |
+
this.element.remove();
|
179 |
+
return this;
|
180 |
+
}
|
181 |
+
});
|
js/livepipe/progressbar.js
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/progressbar
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global document, Prototype, Ajax, Class, PeriodicalExecuter, $, $A, Control */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.ProgressBar requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.ProgressBar requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.ProgressBar = Class.create({
|
18 |
+
initialize: function(container,options){
|
19 |
+
this.progress = 0;
|
20 |
+
this.executer = false;
|
21 |
+
this.active = false;
|
22 |
+
this.poller = false;
|
23 |
+
this.container = $(container);
|
24 |
+
this.containerWidth = this.container.getDimensions().width - (parseInt(this.container.getStyle('border-right-width').replace(/px/,''), 10) + parseInt(this.container.getStyle('border-left-width').replace(/px/,''), 10));
|
25 |
+
this.progressContainer = $(document.createElement('div'));
|
26 |
+
this.progressContainer.setStyle({
|
27 |
+
width: this.containerWidth + 'px',
|
28 |
+
height: '100%',
|
29 |
+
position: 'absolute',
|
30 |
+
top: '0px',
|
31 |
+
right: '0px'
|
32 |
+
});
|
33 |
+
this.container.appendChild(this.progressContainer);
|
34 |
+
this.options = {
|
35 |
+
afterChange: Prototype.emptyFunction,
|
36 |
+
interval: 0.25,
|
37 |
+
step: 1,
|
38 |
+
classNames: {
|
39 |
+
active: 'progress_bar_active',
|
40 |
+
inactive: 'progress_bar_inactive'
|
41 |
+
}
|
42 |
+
};
|
43 |
+
Object.extend(this.options,options || {});
|
44 |
+
this.container.addClassName(this.options.classNames.inactive);
|
45 |
+
this.active = false;
|
46 |
+
},
|
47 |
+
setProgress: function(value){
|
48 |
+
this.progress = value;
|
49 |
+
this.draw();
|
50 |
+
if(this.progress >= 100) {
|
51 |
+
this.stop(false); }
|
52 |
+
this.notify('afterChange',this.progress,this.active);
|
53 |
+
},
|
54 |
+
poll: function (url, interval, ajaxOptions){
|
55 |
+
// Extend the passed ajax options and success callback with our own.
|
56 |
+
ajaxOptions = ajaxOptions || {};
|
57 |
+
var success = ajaxOptions.onSuccess || Prototype.emptyFunction;
|
58 |
+
ajaxOptions.onSuccess = success.wrap(function (callOriginal, request) {
|
59 |
+
this.setProgress(parseInt(request.responseText, 10));
|
60 |
+
if(!this.active) { this.poller.stop(); }
|
61 |
+
callOriginal(request);
|
62 |
+
}).bind(this);
|
63 |
+
|
64 |
+
this.active = true;
|
65 |
+
this.poller = new PeriodicalExecuter(function(){
|
66 |
+
var a = new Ajax.Request(url, ajaxOptions);
|
67 |
+
}.bind(this),interval || 3);
|
68 |
+
},
|
69 |
+
start: function(){
|
70 |
+
this.active = true;
|
71 |
+
this.container.removeClassName(this.options.classNames.inactive);
|
72 |
+
this.container.addClassName(this.options.classNames.active);
|
73 |
+
this.executer = new PeriodicalExecuter(this.step.bind(this,this.options.step),this.options.interval);
|
74 |
+
},
|
75 |
+
stop: function(reset){
|
76 |
+
this.active = false;
|
77 |
+
if(this.executer) {
|
78 |
+
this.executer.stop(); }
|
79 |
+
this.container.removeClassName(this.options.classNames.active);
|
80 |
+
this.container.addClassName(this.options.classNames.inactive);
|
81 |
+
if (typeof reset === 'undefined' || reset === true) {
|
82 |
+
this.reset(); }
|
83 |
+
},
|
84 |
+
step: function(amount){
|
85 |
+
this.active = true;
|
86 |
+
this.setProgress(Math.min(100,this.progress + amount));
|
87 |
+
},
|
88 |
+
reset: function(){
|
89 |
+
this.active = false;
|
90 |
+
this.setProgress(0);
|
91 |
+
},
|
92 |
+
draw: function(){
|
93 |
+
this.progressContainer.setStyle({
|
94 |
+
width: (this.containerWidth - Math.floor((parseInt(this.progress, 10) / 100) * this.containerWidth)) + 'px'
|
95 |
+
});
|
96 |
+
},
|
97 |
+
notify: function(event_name){
|
98 |
+
if(this.options[event_name]) {
|
99 |
+
return [this.options[event_name].apply(this.options[event_name],$A(arguments).slice(1))]; }
|
100 |
+
}
|
101 |
+
});
|
102 |
+
Object.Event.extend(Control.ProgressBar);
|
js/livepipe/rating.js
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/rating
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global document, Prototype, Ajax, Class, Event, $, $A, $F, $R, $break, Control */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.Rating requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.Rating requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.Rating = Class.create({
|
18 |
+
initialize: function(container,options){
|
19 |
+
Control.Rating.instances.push(this);
|
20 |
+
this.value = false;
|
21 |
+
this.links = [];
|
22 |
+
this.container = $(container);
|
23 |
+
this.container.update('');
|
24 |
+
this.options = {
|
25 |
+
min: 1,
|
26 |
+
max: 5,
|
27 |
+
rated: false,
|
28 |
+
input: false,
|
29 |
+
reverse: false,
|
30 |
+
capture: true,
|
31 |
+
multiple: false,
|
32 |
+
classNames: {
|
33 |
+
off: 'rating_off',
|
34 |
+
half: 'rating_half',
|
35 |
+
on: 'rating_on',
|
36 |
+
selected: 'rating_selected'
|
37 |
+
},
|
38 |
+
updateUrl: false,
|
39 |
+
updateParameterName: 'value',
|
40 |
+
updateOptions : {},
|
41 |
+
afterChange: Prototype.emptyFunction
|
42 |
+
};
|
43 |
+
Object.extend(this.options,options || {});
|
44 |
+
if(this.options.value){
|
45 |
+
this.value = this.options.value;
|
46 |
+
delete this.options.value;
|
47 |
+
}
|
48 |
+
if(this.options.input){
|
49 |
+
this.options.input = $(this.options.input);
|
50 |
+
this.options.input.observe('change',function(input){
|
51 |
+
this.setValueFromInput(input);
|
52 |
+
}.bind(this,this.options.input));
|
53 |
+
this.setValueFromInput(this.options.input,true);
|
54 |
+
}
|
55 |
+
var range = $R(this.options.min,this.options.max);
|
56 |
+
(this.options.reverse ? $A(range).reverse() : range).each(function(i){
|
57 |
+
var link = this.buildLink(i);
|
58 |
+
this.container.appendChild(link);
|
59 |
+
this.links.push(link);
|
60 |
+
}.bind(this));
|
61 |
+
this.setValue(this.value || this.options.min - 1,false,true);
|
62 |
+
},
|
63 |
+
buildLink: function(rating){
|
64 |
+
var link = $(document.createElement('a'));
|
65 |
+
link.value = rating;
|
66 |
+
if(this.options.multiple || (!this.options.rated && !this.options.multiple)){
|
67 |
+
link.href = '';
|
68 |
+
link.onmouseover = this.mouseOver.bind(this,link);
|
69 |
+
link.onmouseout = this.mouseOut.bind(this,link);
|
70 |
+
link.onclick = this.click.bindAsEventListener(this,link);
|
71 |
+
}else{
|
72 |
+
link.style.cursor = 'default';
|
73 |
+
link.observe('click',function(event){
|
74 |
+
Event.stop(event);
|
75 |
+
return false;
|
76 |
+
}.bindAsEventListener(this));
|
77 |
+
}
|
78 |
+
link.addClassName(this.options.classNames.off);
|
79 |
+
return link;
|
80 |
+
},
|
81 |
+
disable: function(){
|
82 |
+
this.links.each(function(link){
|
83 |
+
link.onmouseover = Prototype.emptyFunction;
|
84 |
+
link.onmouseout = Prototype.emptyFunction;
|
85 |
+
link.onclick = Prototype.emptyFunction;
|
86 |
+
link.observe('click',function(event){
|
87 |
+
Event.stop(event);
|
88 |
+
return false;
|
89 |
+
}.bindAsEventListener(this));
|
90 |
+
link.style.cursor = 'default';
|
91 |
+
}.bind(this));
|
92 |
+
},
|
93 |
+
setValueFromInput: function(input,prevent_callbacks){
|
94 |
+
this.setValue($F(input),true,prevent_callbacks);
|
95 |
+
},
|
96 |
+
setValue: function(value,force_selected,prevent_callbacks){
|
97 |
+
this.value = value;
|
98 |
+
if(this.options.input){
|
99 |
+
if(this.options.input.options){
|
100 |
+
$A(this.options.input.options).each(function(option,i){
|
101 |
+
if(option.value == this.value){
|
102 |
+
this.options.input.options.selectedIndex = i;
|
103 |
+
throw $break;
|
104 |
+
}
|
105 |
+
}.bind(this));
|
106 |
+
}else {
|
107 |
+
this.options.input.value = this.value; }
|
108 |
+
}
|
109 |
+
this.render(this.value,force_selected);
|
110 |
+
if(!prevent_callbacks){
|
111 |
+
if(this.options.updateUrl){
|
112 |
+
var params = {}, a;
|
113 |
+
params[this.options.updateParameterName] = this.value;
|
114 |
+
a = new Ajax.Request(this.options.updateUrl, Object.extend(
|
115 |
+
this.options.updateOptions, { parameters : params }
|
116 |
+
));
|
117 |
+
}
|
118 |
+
this.notify('afterChange',this.value);
|
119 |
+
}
|
120 |
+
},
|
121 |
+
render: function(rating,force_selected){
|
122 |
+
(this.options.reverse ? this.links.reverse() : this.links).each(function(link,i){
|
123 |
+
if(link.value <= Math.ceil(rating)){
|
124 |
+
link.className = this.options.classNames[link.value <= rating ? 'on' : 'half'];
|
125 |
+
if(this.options.rated || force_selected) {
|
126 |
+
link.addClassName(this.options.classNames.selected); }
|
127 |
+
}else {
|
128 |
+
link.className = this.options.classNames.off; }
|
129 |
+
}.bind(this));
|
130 |
+
},
|
131 |
+
mouseOver: function(link){
|
132 |
+
this.render(link.value,true);
|
133 |
+
},
|
134 |
+
mouseOut: function(link){
|
135 |
+
this.render(this.value);
|
136 |
+
},
|
137 |
+
click: function(event,link){
|
138 |
+
this.options.rated = true;
|
139 |
+
this.setValue((link.value ? link.value : link),true);
|
140 |
+
if(!this.options.multiple) {
|
141 |
+
this.disable(); }
|
142 |
+
if(this.options.capture){
|
143 |
+
Event.stop(event);
|
144 |
+
return false;
|
145 |
+
}
|
146 |
+
}
|
147 |
+
});
|
148 |
+
Object.extend(Control.Rating,{
|
149 |
+
instances: [],
|
150 |
+
findByElementId: function(id){
|
151 |
+
return Control.Rating.instances.find(function(instance){
|
152 |
+
return (instance.container.id && instance.container.id == id);
|
153 |
+
});
|
154 |
+
}
|
155 |
+
});
|
156 |
+
Object.Event.extend(Control.Rating);
|
js/livepipe/resizable.js
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
// script.aculo.us Resizables.js
|
3 |
+
|
4 |
+
// Copyright(c) 2007 - Orr Siloni, Comet Information Systems http://www.comet.co.il/en/
|
5 |
+
//
|
6 |
+
// Resizable.js is freely distributable under the terms of an MIT-style license.
|
7 |
+
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
8 |
+
|
9 |
+
var Resizables = {
|
10 |
+
instances: [],
|
11 |
+
observers: [],
|
12 |
+
|
13 |
+
register: function(resizable) {
|
14 |
+
if(this.instances.length == 0) {
|
15 |
+
this.eventMouseUp = this.endResize.bindAsEventListener(this);
|
16 |
+
this.eventMouseMove = this.updateResize.bindAsEventListener(this);
|
17 |
+
|
18 |
+
Event.observe(document, "mouseup", this.eventMouseUp);
|
19 |
+
Event.observe(document, "mousemove", this.eventMouseMove);
|
20 |
+
}
|
21 |
+
this.instances.push(resizable);
|
22 |
+
},
|
23 |
+
|
24 |
+
unregister: function(resizable) {
|
25 |
+
this.instances = this.instances.reject(function(d) { return d==resizable });
|
26 |
+
if(this.instances.length == 0) {
|
27 |
+
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
28 |
+
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
29 |
+
}
|
30 |
+
},
|
31 |
+
|
32 |
+
activate: function(resizable) {
|
33 |
+
if(resizable.options.delay) {
|
34 |
+
this._timeout = setTimeout(function() {
|
35 |
+
Resizables._timeout = null;
|
36 |
+
Resizables.activeResizable = resizable;
|
37 |
+
}.bind(this), resizable.options.delay);
|
38 |
+
} else {
|
39 |
+
this.activeResizable = resizable;
|
40 |
+
}
|
41 |
+
},
|
42 |
+
|
43 |
+
deactivate: function() {
|
44 |
+
this.activeResizable = null;
|
45 |
+
},
|
46 |
+
|
47 |
+
updateResize: function(event) {
|
48 |
+
if(!this.activeResizable) return;
|
49 |
+
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
50 |
+
// Mozilla-based browsers fire successive mousemove events with
|
51 |
+
// the same coordinates, prevent needless redrawing (moz bug?)
|
52 |
+
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
|
53 |
+
this._lastPointer = pointer;
|
54 |
+
|
55 |
+
this.activeResizable.updateResize(event, pointer);
|
56 |
+
},
|
57 |
+
|
58 |
+
endResize: function(event) {
|
59 |
+
if(this._timeout) {
|
60 |
+
clearTimeout(this._timeout);
|
61 |
+
this._timeout = null;
|
62 |
+
}
|
63 |
+
if(!this.activeResizable) return;
|
64 |
+
this._lastPointer = null;
|
65 |
+
this.activeResizable.endResize(event);
|
66 |
+
this.activeResizable = null;
|
67 |
+
},
|
68 |
+
|
69 |
+
addObserver: function(observer) {
|
70 |
+
this.observers.push(observer);
|
71 |
+
this._cacheObserverCallbacks();
|
72 |
+
},
|
73 |
+
|
74 |
+
removeObserver: function(element) { // element instead of observer fixes mem leaks
|
75 |
+
this.observers = this.observers.reject( function(o) { return o.element==element });
|
76 |
+
this._cacheObserverCallbacks();
|
77 |
+
},
|
78 |
+
|
79 |
+
notify: function(eventName, resizable, event) { // 'onStart', 'onEnd', 'onResize'
|
80 |
+
if(this[eventName+'Count'] > 0)
|
81 |
+
this.observers.each( function(o) {
|
82 |
+
if(o[eventName]) o[eventName](eventName, resizable, event);
|
83 |
+
});
|
84 |
+
if(resizable.options[eventName]) resizable.options[eventName](resizable, event);
|
85 |
+
},
|
86 |
+
|
87 |
+
_cacheObserverCallbacks: function() {
|
88 |
+
['onStart','onEnd','onResize'].each( function(eventName) {
|
89 |
+
Resizables[eventName+'Count'] = Resizables.observers.select(
|
90 |
+
function(o) { return o[eventName]; }
|
91 |
+
).length;
|
92 |
+
});
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
var Resizable = Class.create();
|
97 |
+
Resizable._resizing = {};
|
98 |
+
|
99 |
+
Resizable.prototype = {
|
100 |
+
initialize: function(element){
|
101 |
+
var defaults = {
|
102 |
+
handle: false,
|
103 |
+
snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] }
|
104 |
+
delay: 0,
|
105 |
+
minHeight: false,
|
106 |
+
minwidth: false,
|
107 |
+
maxHeight: false,
|
108 |
+
maxWidth: false
|
109 |
+
}
|
110 |
+
|
111 |
+
this.element = $(element);
|
112 |
+
|
113 |
+
var options = Object.extend(defaults, arguments[1] || {});
|
114 |
+
if(options.handle && typeof options.handle == 'string')
|
115 |
+
this.handle = $(options.handle);
|
116 |
+
else if(options.handle)
|
117 |
+
this.handle = options.handle;
|
118 |
+
|
119 |
+
if(!this.handle) this.handle = this.element;
|
120 |
+
|
121 |
+
this.options = options;
|
122 |
+
this.dragging = false;
|
123 |
+
|
124 |
+
this.eventMouseDown = this.initResize.bindAsEventListener(this);
|
125 |
+
Event.observe(this.handle, "mousedown", this.eventMouseDown);
|
126 |
+
|
127 |
+
Resizables.register(this);
|
128 |
+
},
|
129 |
+
|
130 |
+
destroy: function() {
|
131 |
+
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
|
132 |
+
},
|
133 |
+
|
134 |
+
currentDelta: function() {
|
135 |
+
return([
|
136 |
+
parseInt(Element.getStyle(this.element,'width') || '0'),
|
137 |
+
parseInt(Element.getStyle(this.element,'height') || '0')]);
|
138 |
+
},
|
139 |
+
|
140 |
+
initResize: function(event) {
|
141 |
+
if(typeof Resizable._resizing[this.element] != 'undefined' &&
|
142 |
+
Resizable._resizing[this.element]) return;
|
143 |
+
if(Event.isLeftClick(event)) {
|
144 |
+
// abort on form elements, fixes a Firefox issue
|
145 |
+
var src = Event.element(event);
|
146 |
+
if((tag_name = src.tagName.toUpperCase()) && (
|
147 |
+
tag_name=='INPUT' || tag_name=='SELECT' || tag_name=='OPTION' ||
|
148 |
+
tag_name=='BUTTON' || tag_name=='TEXTAREA')) return;
|
149 |
+
|
150 |
+
this.pointer = [Event.pointerX(event), Event.pointerY(event)];
|
151 |
+
this.size = [parseInt(this.element.getStyle('width')) || 0, parseInt(this.element.getStyle('height')) || 0];
|
152 |
+
|
153 |
+
Resizables.activate(this);
|
154 |
+
Event.stop(event);
|
155 |
+
}
|
156 |
+
},
|
157 |
+
|
158 |
+
startResize: function(event) {
|
159 |
+
this.resizing = true;
|
160 |
+
if(this.options.zindex) {
|
161 |
+
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
|
162 |
+
this.element.style.zIndex = this.options.zindex;
|
163 |
+
}
|
164 |
+
Resizables.notify('onStart', this, event);
|
165 |
+
Resizable._resizing[this.element] = true;
|
166 |
+
},
|
167 |
+
|
168 |
+
updateResize: function(event, pointer) {
|
169 |
+
if(!this.resizing) this.startResize(event);
|
170 |
+
|
171 |
+
Resizables.notify('onResize', this, event);
|
172 |
+
|
173 |
+
this.draw(pointer);
|
174 |
+
if(this.options.change) this.options.change(this);
|
175 |
+
|
176 |
+
// fix AppleWebKit rendering
|
177 |
+
if(Prototype.Browser.WebKit) window.scrollBy(0,0);
|
178 |
+
Event.stop(event);
|
179 |
+
},
|
180 |
+
|
181 |
+
finishResize: function(event, success) {
|
182 |
+
this.resizing = false;
|
183 |
+
Resizables.notify('onEnd', this, event);
|
184 |
+
if(this.options.zindex) this.element.style.zIndex = this.originalZ;
|
185 |
+
Resizable._resizing[this.element] = false;
|
186 |
+
Resizables.deactivate(this);
|
187 |
+
},
|
188 |
+
|
189 |
+
endResize: function(event) {
|
190 |
+
if(!this.resizing) return;
|
191 |
+
this.finishResize(event, true);
|
192 |
+
Event.stop(event);
|
193 |
+
},
|
194 |
+
|
195 |
+
draw: function(point) {
|
196 |
+
var p = [0,1].map(function(i){
|
197 |
+
return (this.size[i] + point[i] - this.pointer[i]);
|
198 |
+
}.bind(this));
|
199 |
+
|
200 |
+
if(this.options.snap) {
|
201 |
+
if(typeof this.options.snap == 'function') {
|
202 |
+
p = this.options.snap(p[0],p[1],this);
|
203 |
+
} else {
|
204 |
+
if(this.options.snap instanceof Array) {
|
205 |
+
p = p.map( function(v, i) {
|
206 |
+
return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
|
207 |
+
} else {
|
208 |
+
p = p.map( function(v) {
|
209 |
+
return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
|
210 |
+
}
|
211 |
+
}}
|
212 |
+
|
213 |
+
var minWidth = (typeof(this.options.minWidth) == 'function') ? this.options.minWidth(this.element) : this.options.minWidth;
|
214 |
+
var maxWidth = (typeof(this.options.maxWidth) == 'function') ? this.options.maxWidth(this.element) : this.options.maxWidth;
|
215 |
+
var minHeight = (typeof(this.options.minHeight) == 'function') ? this.options.minHeight(this.element) : this.options.minHeight;
|
216 |
+
var maxHeight = (typeof(this.options.maxHeight) == 'function') ? this.options.maxHeight(this.element) : this.options.maxHeight;
|
217 |
+
|
218 |
+
if (minWidth && p[0] <= minWidth) p[0] = minWidth;
|
219 |
+
if (maxWidth && p[0] >= maxWidth) p[0] = maxWidth;
|
220 |
+
if (minHeight && p[1] <= minHeight) p[1] = minHeight;
|
221 |
+
if (maxHeight && p[1] >= maxHeight) p[1] = maxHeight;
|
222 |
+
|
223 |
+
var style = this.element.style;
|
224 |
+
if((!this.options.constraint) || (this.options.constraint=='horizontal')){
|
225 |
+
style.width = p[0] + "px";
|
226 |
+
}
|
227 |
+
if((!this.options.constraint) || (this.options.constraint=='vertical')){
|
228 |
+
style.height = p[1] + "px";
|
229 |
+
}
|
230 |
+
|
231 |
+
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
|
232 |
+
}
|
233 |
+
};
|
js/livepipe/scrollbar.js
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/scrollbar
|
7 |
+
* @require prototype.js, slider.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
if(typeof(Prototype) == "undefined")
|
11 |
+
throw "Control.ScrollBar requires Prototype to be loaded.";
|
12 |
+
if(typeof(Control.Slider) == "undefined")
|
13 |
+
throw "Control.ScrollBar requires Control.Slider to be loaded.";
|
14 |
+
if(typeof(Object.Event) == "undefined")
|
15 |
+
throw "Control.ScrollBar requires Object.Event to be loaded.";
|
16 |
+
|
17 |
+
Control.ScrollBar = Class.create({
|
18 |
+
initialize: function(container,track,options){
|
19 |
+
Control.ScrollBar.instances.push(this);
|
20 |
+
this.enabled = false;
|
21 |
+
this.notificationTimeout = false;
|
22 |
+
this.container = $(container);
|
23 |
+
this.boundMouseWheelEvent = this.onMouseWheel.bindAsEventListener(this);
|
24 |
+
this.boundResizeObserver = this.onWindowResize.bind(this);
|
25 |
+
this.track = $(track);
|
26 |
+
this.handle = this.track.firstDescendant();
|
27 |
+
this.options = Object.extend({
|
28 |
+
active_class_name: 'scrolling',
|
29 |
+
apply_active_class_name_to: this.container,
|
30 |
+
notification_timeout_length: 125,
|
31 |
+
handle_minimum_length: 25,
|
32 |
+
scroll_to_smoothing: 0.01,
|
33 |
+
scroll_to_steps: 15,
|
34 |
+
scroll_to_precision: 100,
|
35 |
+
proportional: true,
|
36 |
+
custom_event: null,
|
37 |
+
custom_event_handler: null,
|
38 |
+
scroll_axis: 'vertical',
|
39 |
+
/**
|
40 |
+
* If this value is larger than 0 (e.g. 50), one mouse wheel event will scroll the page
|
41 |
+
* by the given number of pixels (default behaviour in any program). If it is lower than 0,
|
42 |
+
* the scrollbar's default behaviour will be used (scrolls down 1/20 of the page, no matter
|
43 |
+
* how long it is). Initialization with e.g.:
|
44 |
+
* new Control.ScrollBar(
|
45 |
+
document.getElementById('scrollbar_content'),
|
46 |
+
document.getElementById('scrollbar_track'),
|
47 |
+
{ fixed_scroll_distance: 50 });
|
48 |
+
*/
|
49 |
+
fixed_scroll_distance: -1,
|
50 |
+
slider_options: {}
|
51 |
+
},options || {});
|
52 |
+
this.slider = new Control.Slider(this.handle,this.track,Object.extend({
|
53 |
+
axis: this.options.scroll_axis,
|
54 |
+
onSlide: this.onChange.bind(this),
|
55 |
+
onChange: this.onChange.bind(this)
|
56 |
+
},this.options.slider_options));
|
57 |
+
this.recalculateLayout();
|
58 |
+
Event.observe(window,'resize',this.boundResizeObserver);
|
59 |
+
if (this.options.custom_event) {
|
60 |
+
if (Object.isFunction(this.options.custom_event_handler)) {
|
61 |
+
this.container.observe(this.options.custom_event, this.options.custom_event_handler);
|
62 |
+
} else {
|
63 |
+
this.container.observe(this.options.custom_event, this.boundResizeObserver);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
this.handle.observe('mousedown',function(){
|
67 |
+
if(this.auto_sliding_executer)
|
68 |
+
this.auto_sliding_executer.stop();
|
69 |
+
}.bind(this));
|
70 |
+
},
|
71 |
+
destroy: function(){
|
72 |
+
Event.stopObserving(window,'resize',this.boundResizeObserver);
|
73 |
+
if(this.options.active_class_name)
|
74 |
+
$(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
|
75 |
+
if (this.options.custom_event) {
|
76 |
+
this.container.stopObserving(this.options.custom_event);
|
77 |
+
}
|
78 |
+
},
|
79 |
+
scrollLength: function(){
|
80 |
+
return (this.options.scroll_axis == 'vertical') ? this.container.scrollHeight : this.container.scrollWidth;
|
81 |
+
},
|
82 |
+
offsetLength: function(){
|
83 |
+
return (this.options.scroll_axis == 'vertical') ? this.container.offsetHeight : this.container.offsetWidth;
|
84 |
+
},
|
85 |
+
enable: function(){
|
86 |
+
this.enabled = true;
|
87 |
+
this.container.observe('mouse:wheel',this.boundMouseWheelEvent);
|
88 |
+
this.slider.setEnabled();
|
89 |
+
this.track.show();
|
90 |
+
if(this.options.active_class_name)
|
91 |
+
$(this.options.apply_active_class_name_to).addClassName(this.options.active_class_name);
|
92 |
+
this.notify('enabled');
|
93 |
+
},
|
94 |
+
disable: function(){
|
95 |
+
this.enabled = false;
|
96 |
+
this.container.stopObserving('mouse:wheel',this.boundMouseWheelEvent);
|
97 |
+
this.slider.setDisabled();
|
98 |
+
this.track.hide();
|
99 |
+
if(this.options.active_class_name)
|
100 |
+
$(this.options.apply_active_class_name_to).removeClassName(this.options.active_class_name);
|
101 |
+
this.notify('disabled');
|
102 |
+
this.reset();
|
103 |
+
},
|
104 |
+
reset: function(){
|
105 |
+
this.slider.setValue(0);
|
106 |
+
},
|
107 |
+
recalculateLayout: function(){
|
108 |
+
if(this.scrollLength() <= this.offsetLength())
|
109 |
+
this.disable();
|
110 |
+
else{
|
111 |
+
this.enable();
|
112 |
+
this.slider.trackLength = this.slider.maximumOffset() - this.slider.minimumOffset();
|
113 |
+
if(this.options.proportional){
|
114 |
+
this.slider.handleLength = Math.max(this.offsetLength() * (this.offsetLength() / this.scrollLength()),this.options.handle_minimum_length);
|
115 |
+
if (this.options.scroll_axis == 'vertical')
|
116 |
+
this.handle.style.height = this.slider.handleLength + 'px';
|
117 |
+
else
|
118 |
+
this.handle.style.width = this.slider.handleLength + 'px';
|
119 |
+
}
|
120 |
+
this.scrollBy(0);
|
121 |
+
}
|
122 |
+
},
|
123 |
+
onWindowResize: function(){
|
124 |
+
this.recalculateLayout();
|
125 |
+
this.scrollBy(0);
|
126 |
+
},
|
127 |
+
onMouseWheel: function(event){
|
128 |
+
if(this.auto_sliding_executer) {
|
129 |
+
this.auto_sliding_executer.stop();
|
130 |
+
}
|
131 |
+
if (this.options.fixed_scroll_distance > 0) {
|
132 |
+
// Move the content by the given number of pixels each wheel event
|
133 |
+
this.slider.setValueBy(-(this.options.fixed_scroll_distance * event.memo.delta / (this.scrollLength()-this.slider.trackLength)));
|
134 |
+
} else {
|
135 |
+
// Move the content by 1/20 of the page
|
136 |
+
this.slider.setValueBy(-(event.memo.delta / 20));
|
137 |
+
}
|
138 |
+
event.stop();
|
139 |
+
return false;
|
140 |
+
},
|
141 |
+
onChange: function(value){
|
142 |
+
var scroll_pos = Math.round(value / this.slider.maximum * (this.scrollLength() - this.offsetLength()));
|
143 |
+
if (this.options.scroll_axis == 'vertical')
|
144 |
+
this.container.scrollTop = scroll_pos;
|
145 |
+
else
|
146 |
+
this.container.scrollLeft = scroll_pos;
|
147 |
+
if(this.notification_timeout)
|
148 |
+
window.clearTimeout(this.notificationTimeout);
|
149 |
+
this.notificationTimeout = window.setTimeout(function(){
|
150 |
+
this.notify('change',value);
|
151 |
+
}.bind(this),this.options.notification_timeout_length);
|
152 |
+
},
|
153 |
+
getCurrentMaximumDelta: function(){
|
154 |
+
return this.slider.maximum * (this.scrollLength() - this.offsetLength());
|
155 |
+
},
|
156 |
+
getContainerOffset: function(element) {
|
157 |
+
var offset = element.positionedOffset();
|
158 |
+
while (element.getOffsetParent() != this.container)
|
159 |
+
{
|
160 |
+
element = element.getOffsetParent();
|
161 |
+
offset[0] += element.positionedOffset()[0];
|
162 |
+
offset[1] += element.positionedOffset()[1];
|
163 |
+
offset.top += element.positionedOffset().top;
|
164 |
+
offset.left += element.positionedOffset().left;
|
165 |
+
}
|
166 |
+
return offset;
|
167 |
+
},
|
168 |
+
getDeltaToElement: function(element){
|
169 |
+
|
170 |
+
if (this.options.scroll_axis == 'vertical')
|
171 |
+
return this.slider.maximum * ((this.getContainerOffset(element).top + (element.getHeight() / 2)) - (this.container.getHeight() / 2));
|
172 |
+
else
|
173 |
+
return this.slider.maximum * ((this.getContainerOffset(element).left + (element.getWidth() / 2)) - (this.container.getWidth() / 2));
|
174 |
+
},
|
175 |
+
scrollTo: function(y,animate){
|
176 |
+
var precision = this.options.scroll_to_precision,
|
177 |
+
current_maximum_delta = this.getCurrentMaximumDelta();
|
178 |
+
if (precision == 'auto')
|
179 |
+
precision = Math.pow(10, Math.ceil(Math.log(current_maximum_delta)/Math.log(10)));
|
180 |
+
if(y == 'top')
|
181 |
+
y = 0;
|
182 |
+
else if(y == 'bottom')
|
183 |
+
y = current_maximum_delta;
|
184 |
+
else if(typeof(y) != "number")
|
185 |
+
y = this.getDeltaToElement($(y));
|
186 |
+
if(this.enabled){
|
187 |
+
y = Math.max(0,Math.min(y,current_maximum_delta));
|
188 |
+
if(this.auto_sliding_executer)
|
189 |
+
this.auto_sliding_executer.stop();
|
190 |
+
var target_value = y / current_maximum_delta;
|
191 |
+
var original_slider_value = this.slider.value;
|
192 |
+
var delta = (target_value - original_slider_value) * current_maximum_delta;
|
193 |
+
if(animate){
|
194 |
+
this.auto_sliding_executer = new PeriodicalExecuter(function(){
|
195 |
+
if(Math.round(this.slider.value * precision) / precision < Math.round(target_value * precision) / precision || Math.round(this.slider.value * precision) / precision > Math.round(target_value * precision) / precision){
|
196 |
+
this.scrollBy(delta / this.options.scroll_to_steps);
|
197 |
+
}else{
|
198 |
+
this.auto_sliding_executer.stop();
|
199 |
+
this.auto_sliding_executer = null;
|
200 |
+
if(typeof(animate) == "function")
|
201 |
+
animate();
|
202 |
+
}
|
203 |
+
}.bind(this),this.options.scroll_to_smoothing);
|
204 |
+
}else
|
205 |
+
this.scrollBy(delta);
|
206 |
+
}else if(typeof(animate) == "function")
|
207 |
+
animate();
|
208 |
+
},
|
209 |
+
scrollBy: function(y){
|
210 |
+
if(!this.enabled)
|
211 |
+
return false;
|
212 |
+
this.slider.setValueBy(y / (this.getCurrentMaximumDelta() == 0 ? 1 : this.getCurrentMaximumDelta()) );
|
213 |
+
}
|
214 |
+
});
|
215 |
+
Object.extend(Control.ScrollBar,
|
216 |
+
{
|
217 |
+
instances: [],
|
218 |
+
|
219 |
+
findByElementId: function(id)
|
220 |
+
{
|
221 |
+
return Control.ScrollBar.instances.find(function(instance)
|
222 |
+
{
|
223 |
+
return (instance.container.id && instance.container.id == id);
|
224 |
+
});
|
225 |
+
}
|
226 |
+
});
|
227 |
+
Object.Event.extend(Control.ScrollBar);
|
js/livepipe/selection.js
ADDED
@@ -0,0 +1,459 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/selection
|
7 |
+
* @require prototype.js, effects.js, draggable.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global window, document, Prototype, Element, Event, $, $$, $break, Control, Draggable */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.Selection requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.Selection requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.Selection = {
|
18 |
+
options: {
|
19 |
+
resize_layout_timeout: 125,
|
20 |
+
selected: Prototype.emptyFunction,
|
21 |
+
deselected: Prototype.emptyFunction,
|
22 |
+
change: Prototype.emptyFunction,
|
23 |
+
selection_id: 'control_selection',
|
24 |
+
selection_style: {
|
25 |
+
zIndex: 999,
|
26 |
+
cursor: 'default',
|
27 |
+
border: '1px dotted #000'
|
28 |
+
},
|
29 |
+
filter: function(element){
|
30 |
+
return true;
|
31 |
+
},
|
32 |
+
drag_proxy: false,
|
33 |
+
drag_proxy_threshold: 1,
|
34 |
+
drag_proxy_options: {}
|
35 |
+
},
|
36 |
+
selectableElements: [],
|
37 |
+
elements: [],
|
38 |
+
selectableObjects: [],
|
39 |
+
objects: [],
|
40 |
+
active: false,
|
41 |
+
container: false,
|
42 |
+
resizeTimeout: false,
|
43 |
+
load: function(options){
|
44 |
+
Control.Selection.options = Object.extend(Control.Selection.options,options || {});
|
45 |
+
Control.Selection.selection_div = $(document.createElement('div'));
|
46 |
+
Control.Selection.selection_div.id = Control.Selection.options.selection_id;
|
47 |
+
Control.Selection.selection_div.style.display = 'none';
|
48 |
+
Control.Selection.selection_div.setStyle(Control.Selection.options.selection_style);
|
49 |
+
Control.Selection.border_width = parseInt(Control.Selection.selection_div.getStyle('border-top-width'), 10) * 2;
|
50 |
+
Control.Selection.container = Prototype.Browser.IE ? window.container : window;
|
51 |
+
$(document.body).insert(Control.Selection.selection_div);
|
52 |
+
Control.Selection.enable();
|
53 |
+
if(Control.Selection.options.drag_proxy && typeof(Draggable) != 'undefined') {
|
54 |
+
Control.Selection.DragProxy.load(); }
|
55 |
+
Event.observe(window,'resize',function(){
|
56 |
+
if(Control.Selection.resizeTimeout) {
|
57 |
+
window.clearTimeout(Control.Selection.resizeTimeout); }
|
58 |
+
Control.Selection.resizeTimeout = window.setTimeout(Control.Selection.recalculateLayout,Control.Selection.options.resize_layout_timeout);
|
59 |
+
});
|
60 |
+
if(Prototype.Browser.IE){
|
61 |
+
var body = $$('body').first();
|
62 |
+
body.observe('mouseleave',Control.Selection.stop);
|
63 |
+
body.observe('mouseup',Control.Selection.stop);
|
64 |
+
}
|
65 |
+
},
|
66 |
+
enable: function(){
|
67 |
+
if(Prototype.Browser.IE){
|
68 |
+
document.onselectstart = function(){
|
69 |
+
return false;
|
70 |
+
};
|
71 |
+
}
|
72 |
+
Event.observe(Control.Selection.container,'mousedown',Control.Selection.start);
|
73 |
+
Event.observe(Control.Selection.container,'mouseup',Control.Selection.stop);
|
74 |
+
},
|
75 |
+
disable: function(){
|
76 |
+
if(Prototype.Browser.IE){
|
77 |
+
document.onselectstart = function(){
|
78 |
+
return true;
|
79 |
+
};
|
80 |
+
}
|
81 |
+
Event.stopObserving(Control.Selection.container,'mousedown',Control.Selection.start);
|
82 |
+
Event.stopObserving(Control.Selection.container,'mouseup',Control.Selection.stop);
|
83 |
+
},
|
84 |
+
recalculateLayout: function(){
|
85 |
+
Control.Selection.selectableElements.each(function(element){
|
86 |
+
var dimensions = element.getDimensions();
|
87 |
+
var offset = element.cumulativeOffset();
|
88 |
+
var scroll_offset = element.cumulativeScrollOffset();
|
89 |
+
if(!element._control_selection) {
|
90 |
+
element._control_selection = {}; }
|
91 |
+
element._control_selection.top = offset[1] - scroll_offset[1];
|
92 |
+
element._control_selection.left = offset[0] - scroll_offset[0];
|
93 |
+
element._control_selection.width = dimensions.width;
|
94 |
+
element._control_selection.height = dimensions.height;
|
95 |
+
});
|
96 |
+
},
|
97 |
+
addSelectable: function(element,object,activation_targets,activation_target_callback){
|
98 |
+
element = $(element);
|
99 |
+
if(activation_targets) {
|
100 |
+
activation_targets = activation_targets.each ? activation_targets : [activation_targets]; }
|
101 |
+
var dimensions = element.getDimensions();
|
102 |
+
var offset = Element.cumulativeOffset(element);
|
103 |
+
element._control_selection = {
|
104 |
+
activation_targets: activation_targets,
|
105 |
+
is_selected: false,
|
106 |
+
top: offset[1],
|
107 |
+
left: offset[0],
|
108 |
+
width: dimensions.width,
|
109 |
+
height: dimensions.height,
|
110 |
+
activationTargetMouseMove: function(){
|
111 |
+
Control.Selection.notify('activationTargetMouseMove',element);
|
112 |
+
if(activation_targets){
|
113 |
+
activation_targets.each(function(activation_target){
|
114 |
+
activation_target.stopObserving('mousemove',element._control_selection.activationTargetMouseMove);
|
115 |
+
});
|
116 |
+
}
|
117 |
+
Control.Selection.DragProxy.container.stopObserving('mousemove',element._control_selection.activationTargetMouseMove);
|
118 |
+
},
|
119 |
+
activationTargetMouseDown: function(event){
|
120 |
+
if(!Control.Selection.elements.include(element)) {
|
121 |
+
Control.Selection.select(element); }
|
122 |
+
Control.Selection.DragProxy.start(event);
|
123 |
+
Control.Selection.DragProxy.container.hide();
|
124 |
+
if(activation_targets){
|
125 |
+
activation_targets.each(function(activation_target){
|
126 |
+
activation_target.observe('mousemove',element._control_selection.activationTargetMouseMove);
|
127 |
+
});
|
128 |
+
}
|
129 |
+
Control.Selection.DragProxy.container.observe('mousemove',element._control_selection.activationTargetMouseMove);
|
130 |
+
},
|
131 |
+
activationTargetClick: function(){
|
132 |
+
Control.Selection.select(element);
|
133 |
+
if(typeof(activation_target_callback) == "function") {
|
134 |
+
activation_target_callback(); }
|
135 |
+
if(activation_targets){
|
136 |
+
activation_targets.each(function(activation_target){
|
137 |
+
activation_target.stopObserving('mousemove',element._control_selection.activationTargetMouseMove);
|
138 |
+
});
|
139 |
+
}
|
140 |
+
Control.Selection.DragProxy.container.stopObserving('mousemove',element._control_selection.activationTargetMouseMove);
|
141 |
+
}
|
142 |
+
};
|
143 |
+
element.onselectstart = function(){
|
144 |
+
return false;
|
145 |
+
};
|
146 |
+
element.unselectable = 'on';
|
147 |
+
element.style.MozUserSelect = 'none';
|
148 |
+
if(activation_targets){
|
149 |
+
activation_targets.each(function(activation_target){
|
150 |
+
activation_target.observe('mousedown',element._control_selection.activationTargetMouseDown);
|
151 |
+
activation_target.observe('click',element._control_selection.activationTargetClick);
|
152 |
+
});
|
153 |
+
}
|
154 |
+
Control.Selection.selectableElements.push(element);
|
155 |
+
Control.Selection.selectableObjects.push(object);
|
156 |
+
},
|
157 |
+
removeSelectable: function(element){
|
158 |
+
element = $(element);
|
159 |
+
if(element._control_selection.activation_targets){
|
160 |
+
element._control_selection.activation_targets.each(function(activation_target){
|
161 |
+
activation_target.stopObserving('mousedown',element._control_selection.activationTargetMouseDown);
|
162 |
+
});
|
163 |
+
element._control_selection.activation_targets.each(function(activation_target){
|
164 |
+
activation_target.stopObserving('click',element._control_selection.activationTargetClick);
|
165 |
+
});
|
166 |
+
}
|
167 |
+
element._control_selection = null;
|
168 |
+
element.onselectstart = function() {
|
169 |
+
return true;
|
170 |
+
};
|
171 |
+
element.unselectable = 'off';
|
172 |
+
element.style.MozUserSelect = '';
|
173 |
+
var position = 0;
|
174 |
+
Control.Selection.selectableElements.each(function(selectable_element,i){
|
175 |
+
if(selectable_element == element){
|
176 |
+
position = i;
|
177 |
+
throw $break;
|
178 |
+
}
|
179 |
+
});
|
180 |
+
Control.Selection.selectableElements = Control.Selection.selectableElements.without(element);
|
181 |
+
Control.Selection.selectableObjects = Control.Selection.selectableObjects.slice(0,position).concat(Control.Selection.selectableObjects.slice(position + 1));
|
182 |
+
},
|
183 |
+
select: function(selected_elements){
|
184 |
+
if(typeof(selected_elements) == "undefined" || !selected_elements) {
|
185 |
+
selected_elements = []; }
|
186 |
+
if(!selected_elements.each && !selected_elements._each) {
|
187 |
+
selected_elements = [selected_elements]; }
|
188 |
+
//comparing the arrays directly wouldn't equate to true in safari so we need to compare each item
|
189 |
+
var selected_items_have_changed = !(Control.Selection.elements.length == selected_elements.length && Control.Selection.elements.all(function(item,i){
|
190 |
+
return selected_elements[i] == item;
|
191 |
+
}));
|
192 |
+
if(!selected_items_have_changed) {
|
193 |
+
return; }
|
194 |
+
var selected_objects_indexed_by_element = {};
|
195 |
+
var selected_objects = selected_elements.collect(function(selected_element){
|
196 |
+
var selected_object = Control.Selection.selectableObjects[Control.Selection.selectableElements.indexOf(selected_element)];
|
197 |
+
selected_objects_indexed_by_element[selected_element] = selected_object;
|
198 |
+
return selected_object;
|
199 |
+
});
|
200 |
+
if(Control.Selection.elements.length === 0 && selected_elements.length !== 0){
|
201 |
+
selected_elements.each(function(element){
|
202 |
+
Control.Selection.notify('selected',element,selected_objects_indexed_by_element[element]);
|
203 |
+
});
|
204 |
+
}else{
|
205 |
+
Control.Selection.elements.each(function(element){
|
206 |
+
if(!selected_elements.include(element)){
|
207 |
+
Control.Selection.notify('deselected',element,selected_objects_indexed_by_element[element]);
|
208 |
+
}
|
209 |
+
});
|
210 |
+
selected_elements.each(function(element){
|
211 |
+
if(!Control.Selection.elements.include(element)){
|
212 |
+
Control.Selection.notify('selected',element,selected_objects_indexed_by_element[element]);
|
213 |
+
}
|
214 |
+
});
|
215 |
+
}
|
216 |
+
Control.Selection.elements = selected_elements;
|
217 |
+
Control.Selection.objects = selected_objects;
|
218 |
+
Control.Selection.notify('change',Control.Selection.elements,Control.Selection.objects);
|
219 |
+
},
|
220 |
+
deselect: function(){
|
221 |
+
if(Control.Selection.notify('deselect') === false) {
|
222 |
+
return false; }
|
223 |
+
Control.Selection.elements.each(function(element){
|
224 |
+
Control.Selection.notify('deselected',element,Control.Selection.selectableObjects[Control.Selection.selectableElements.indexOf(element)]);
|
225 |
+
});
|
226 |
+
Control.Selection.objects = [];
|
227 |
+
Control.Selection.elements = [];
|
228 |
+
Control.Selection.notify('change',Control.Selection.objects,Control.Selection.elements);
|
229 |
+
return true;
|
230 |
+
},
|
231 |
+
//private
|
232 |
+
start: function(event){
|
233 |
+
if(!event.isLeftClick() || Control.Selection.notify('start',event) === false) {
|
234 |
+
return false; }
|
235 |
+
if(!event.shiftKey && !event.altKey) {
|
236 |
+
Control.Selection.deselect(); }
|
237 |
+
Event.observe(Control.Selection.container,'mousemove',Control.Selection.onMouseMove);
|
238 |
+
Event.stop(event);
|
239 |
+
return false;
|
240 |
+
},
|
241 |
+
stop: function(){
|
242 |
+
Event.stopObserving(Control.Selection.container,'mousemove',Control.Selection.onMouseMove);
|
243 |
+
Control.Selection.active = false;
|
244 |
+
Control.Selection.selection_div.setStyle({
|
245 |
+
display: 'none',
|
246 |
+
top: null,
|
247 |
+
left: null,
|
248 |
+
width: null,
|
249 |
+
height: null
|
250 |
+
});
|
251 |
+
Control.Selection.start_mouse_coordinates = {};
|
252 |
+
Control.Selection.current_mouse_coordinates = {};
|
253 |
+
},
|
254 |
+
mouseCoordinatesFromEvent: function(event){
|
255 |
+
return {
|
256 |
+
x: Event.pointerX(event),
|
257 |
+
y: Event.pointerY(event)
|
258 |
+
};
|
259 |
+
},
|
260 |
+
onClick: function(event,element,source){
|
261 |
+
var selection = [];
|
262 |
+
if(event.shiftKey){
|
263 |
+
selection = Control.Selection.elements.clone();
|
264 |
+
if(!selection.include(element)) {
|
265 |
+
selection.push(element); }
|
266 |
+
}else if(event.altKey){
|
267 |
+
selection = Control.Selection.elements.clone();
|
268 |
+
if(selection.include(element)) {
|
269 |
+
selection = selection.without(element); }
|
270 |
+
}else{
|
271 |
+
selection = [element];
|
272 |
+
}
|
273 |
+
Control.Selection.select(selection);
|
274 |
+
if(source == 'click') {
|
275 |
+
Event.stop(event); }
|
276 |
+
},
|
277 |
+
onMouseMove: function(event){
|
278 |
+
if(!Control.Selection.active){
|
279 |
+
Control.Selection.active = true;
|
280 |
+
Control.Selection.start_mouse_coordinates = Control.Selection.mouseCoordinatesFromEvent(event);
|
281 |
+
}else{
|
282 |
+
Control.Selection.current_mouse_coordinates = Control.Selection.mouseCoordinatesFromEvent(event);
|
283 |
+
Control.Selection.drawSelectionDiv();
|
284 |
+
var current_selection = Control.Selection.selectableElements.findAll(function(element){
|
285 |
+
return Control.Selection.options.filter(element) && Control.Selection.elementWithinSelection(element);
|
286 |
+
});
|
287 |
+
if(event.shiftKey && !event.altKey){
|
288 |
+
Control.Selection.elements.each(function(element){
|
289 |
+
if(!current_selection.include(element)) {
|
290 |
+
current_selection.push(element); }
|
291 |
+
});
|
292 |
+
}else if(event.altKey && !event.shiftKey){
|
293 |
+
current_selection = Control.Selection.elements.findAll(function(element){
|
294 |
+
return !current_selection.include(element);
|
295 |
+
});
|
296 |
+
}
|
297 |
+
Control.Selection.select(current_selection);
|
298 |
+
}
|
299 |
+
},
|
300 |
+
drawSelectionDiv: function(){
|
301 |
+
if(Control.Selection.start_mouse_coordinates == Control.Selection.current_mouse_coordinates){
|
302 |
+
Control.Selection.selection_div.style.display = 'none';
|
303 |
+
}else{
|
304 |
+
Control.Selection.viewport = document.viewport.getDimensions();
|
305 |
+
Control.Selection.selection_div.style.position = 'absolute';
|
306 |
+
Control.Selection.current_direction = (Control.Selection.start_mouse_coordinates.y > Control.Selection.current_mouse_coordinates.y ? 'N' : 'S') + (Control.Selection.start_mouse_coordinates.x < Control.Selection.current_mouse_coordinates.x ? 'E' : 'W');
|
307 |
+
Control.Selection.selection_div.setStyle(Control.Selection['dimensionsFor' + Control.Selection.current_direction]());
|
308 |
+
Control.Selection.selection_div.style.display = 'block';
|
309 |
+
}
|
310 |
+
},
|
311 |
+
dimensionsForNW: function(){
|
312 |
+
return {
|
313 |
+
top: (Control.Selection.start_mouse_coordinates.y - (Control.Selection.start_mouse_coordinates.y - Control.Selection.current_mouse_coordinates.y)) + 'px',
|
314 |
+
left: (Control.Selection.start_mouse_coordinates.x - (Control.Selection.start_mouse_coordinates.x - Control.Selection.current_mouse_coordinates.x)) + 'px',
|
315 |
+
width: (Control.Selection.start_mouse_coordinates.x - Control.Selection.current_mouse_coordinates.x) + 'px',
|
316 |
+
height: (Control.Selection.start_mouse_coordinates.y - Control.Selection.current_mouse_coordinates.y) + 'px'
|
317 |
+
};
|
318 |
+
},
|
319 |
+
dimensionsForNE: function(){
|
320 |
+
return {
|
321 |
+
top: (Control.Selection.start_mouse_coordinates.y - (Control.Selection.start_mouse_coordinates.y - Control.Selection.current_mouse_coordinates.y)) + 'px',
|
322 |
+
left: Control.Selection.start_mouse_coordinates.x + 'px',
|
323 |
+
width: Math.min((Control.Selection.viewport.width - Control.Selection.start_mouse_coordinates.x) - Control.Selection.border_width,Control.Selection.current_mouse_coordinates.x - Control.Selection.start_mouse_coordinates.x) + 'px',
|
324 |
+
height: (Control.Selection.start_mouse_coordinates.y - Control.Selection.current_mouse_coordinates.y) + 'px'
|
325 |
+
};
|
326 |
+
},
|
327 |
+
dimensionsForSE: function(){
|
328 |
+
return {
|
329 |
+
top: Control.Selection.start_mouse_coordinates.y + 'px',
|
330 |
+
left: Control.Selection.start_mouse_coordinates.x + 'px',
|
331 |
+
width: Math.min((Control.Selection.viewport.width - Control.Selection.start_mouse_coordinates.x) - Control.Selection.border_width,Control.Selection.current_mouse_coordinates.x - Control.Selection.start_mouse_coordinates.x) + 'px',
|
332 |
+
height: Math.min((Control.Selection.viewport.height - Control.Selection.start_mouse_coordinates.y) - Control.Selection.border_width,Control.Selection.current_mouse_coordinates.y - Control.Selection.start_mouse_coordinates.y) + 'px'
|
333 |
+
};
|
334 |
+
},
|
335 |
+
dimensionsForSW: function(){
|
336 |
+
return {
|
337 |
+
top: Control.Selection.start_mouse_coordinates.y + 'px',
|
338 |
+
left: (Control.Selection.start_mouse_coordinates.x - (Control.Selection.start_mouse_coordinates.x - Control.Selection.current_mouse_coordinates.x)) + 'px',
|
339 |
+
width: (Control.Selection.start_mouse_coordinates.x - Control.Selection.current_mouse_coordinates.x) + 'px',
|
340 |
+
height: Math.min((Control.Selection.viewport.height - Control.Selection.start_mouse_coordinates.y) - Control.Selection.border_width,Control.Selection.current_mouse_coordinates.y - Control.Selection.start_mouse_coordinates.y) + 'px'
|
341 |
+
};
|
342 |
+
},
|
343 |
+
inBoundsForNW: function(element,selection){
|
344 |
+
return (
|
345 |
+
((element.left > selection.left || element.right > selection.left) && selection.right > element.left) &&
|
346 |
+
((element.top > selection.top || element.bottom > selection.top) && selection.bottom > element.top)
|
347 |
+
);
|
348 |
+
},
|
349 |
+
inBoundsForNE: function(element,selection){
|
350 |
+
return (
|
351 |
+
((element.left < selection.right || element.left < selection.right) && selection.left < element.right) &&
|
352 |
+
((element.top > selection.top || element.bottom > selection.top) && selection.bottom > element.top)
|
353 |
+
);
|
354 |
+
},
|
355 |
+
inBoundsForSE: function(element,selection){
|
356 |
+
return (
|
357 |
+
((element.left < selection.right || element.left < selection.right) && selection.left < element.right) &&
|
358 |
+
((element.bottom < selection.bottom || element.top < selection.bottom) && selection.top < element.bottom)
|
359 |
+
);
|
360 |
+
},
|
361 |
+
inBoundsForSW: function(element,selection){
|
362 |
+
return (
|
363 |
+
((element.left > selection.left || element.right > selection.left) && selection.right > element.left) &&
|
364 |
+
((element.bottom < selection.bottom || element.top < selection.bottom) && selection.top < element.bottom)
|
365 |
+
);
|
366 |
+
},
|
367 |
+
elementWithinSelection: function(element){
|
368 |
+
if(Control.Selection['inBoundsFor' + Control.Selection.current_direction]({
|
369 |
+
top: element._control_selection.top,
|
370 |
+
left: element._control_selection.left,
|
371 |
+
bottom: element._control_selection.top + element._control_selection.height,
|
372 |
+
right: element._control_selection.left + element._control_selection.width
|
373 |
+
},{
|
374 |
+
top: parseInt(Control.Selection.selection_div.style.top, 10),
|
375 |
+
left: parseInt(Control.Selection.selection_div.style.left, 10),
|
376 |
+
bottom: parseInt(Control.Selection.selection_div.style.top, 10) + parseInt(Control.Selection.selection_div.style.height, 10),
|
377 |
+
right: parseInt(Control.Selection.selection_div.style.left, 10) + parseInt(Control.Selection.selection_div.style.width, 10)
|
378 |
+
})){
|
379 |
+
element._control_selection.is_selected = true;
|
380 |
+
return true;
|
381 |
+
}else{
|
382 |
+
element._control_selection.is_selected = false;
|
383 |
+
return false;
|
384 |
+
}
|
385 |
+
},
|
386 |
+
DragProxy: {
|
387 |
+
active: false,
|
388 |
+
xorigin: 0,
|
389 |
+
yorigin: 0,
|
390 |
+
load: function(){
|
391 |
+
Control.Selection.DragProxy.container = $(document.createElement('div'));
|
392 |
+
Control.Selection.DragProxy.container.id = 'control_selection_drag_proxy';
|
393 |
+
Control.Selection.DragProxy.container.setStyle({
|
394 |
+
position: 'absolute',
|
395 |
+
top: '1px',
|
396 |
+
left: '1px',
|
397 |
+
zIndex: 99999
|
398 |
+
});
|
399 |
+
Control.Selection.DragProxy.container.hide();
|
400 |
+
document.body.appendChild(Control.Selection.DragProxy.container);
|
401 |
+
Control.Selection.observe('selected',Control.Selection.DragProxy.selected);
|
402 |
+
Control.Selection.observe('deselected',Control.Selection.DragProxy.deselected);
|
403 |
+
},
|
404 |
+
start: function(event){
|
405 |
+
if(event.isRightClick()){
|
406 |
+
Control.Selection.DragProxy.container.hide();
|
407 |
+
return;
|
408 |
+
}
|
409 |
+
if(Control.Selection.DragProxy.xorigin == Event.pointerX(event) && Control.Selection.DragProxy.yorigin == Event.pointerY(event)) {
|
410 |
+
return; }
|
411 |
+
Control.Selection.DragProxy.active = true;
|
412 |
+
Control.Selection.DragProxy.container.setStyle({
|
413 |
+
position: 'absolute',
|
414 |
+
top: Event.pointerY(event) + 'px',
|
415 |
+
left: Event.pointerX(event) + 'px'
|
416 |
+
});
|
417 |
+
Control.Selection.DragProxy.container.observe('mouseup',Control.Selection.DragProxy.onMouseUp);
|
418 |
+
Control.Selection.DragProxy.container.show();
|
419 |
+
Control.Selection.DragProxy.container._draggable = new Draggable(Control.Selection.DragProxy.container,Object.extend({
|
420 |
+
onEnd: Control.Selection.DragProxy.stop
|
421 |
+
},Control.Selection.options.drag_proxy_options));
|
422 |
+
Control.Selection.DragProxy.container._draggable.eventMouseDown(event);
|
423 |
+
Control.Selection.DragProxy.notify('start',Control.Selection.DragProxy.container,Control.Selection.elements);
|
424 |
+
},
|
425 |
+
stop: function(){
|
426 |
+
window.setTimeout(function(){
|
427 |
+
Control.Selection.DragProxy.active = false;
|
428 |
+
Control.Selection.DragProxy.container.hide();
|
429 |
+
if(Control.Selection.DragProxy.container._draggable){
|
430 |
+
Control.Selection.DragProxy.container._draggable.destroy();
|
431 |
+
Control.Selection.DragProxy.container._draggable = null;
|
432 |
+
}
|
433 |
+
Control.Selection.DragProxy.notify('stop');
|
434 |
+
},1);
|
435 |
+
},
|
436 |
+
onClick: function(event){
|
437 |
+
Control.Selection.DragProxy.xorigin = Event.pointerX(event);
|
438 |
+
Control.Selection.DragProxy.yorigin = Event.pointerY(event);
|
439 |
+
if(event.isRightClick()) {
|
440 |
+
Control.Selection.DragProxy.container.hide(); }
|
441 |
+
if(Control.Selection.elements.length >= Control.Selection.options.drag_proxy_threshold && !(event.shiftKey || event.altKey) && (Control.Selection.DragProxy.xorigin != Event.pointerX(event) || Control.Selection.DragProxy.yorigin != Event.pointerY(event))){
|
442 |
+
Control.Selection.DragProxy.start(event);
|
443 |
+
Event.stop(event);
|
444 |
+
}
|
445 |
+
},
|
446 |
+
onMouseUp: function(event){
|
447 |
+
Control.Selection.DragProxy.stop();
|
448 |
+
Control.Selection.DragProxy.container.stopObserving('mouseup',Control.Selection.DragProxy.onMouseUp);
|
449 |
+
},
|
450 |
+
selected: function(element){
|
451 |
+
element.observe('mousedown',Control.Selection.DragProxy.onClick);
|
452 |
+
},
|
453 |
+
deselected: function(element){
|
454 |
+
element.stopObserving('mousedown',Control.Selection.DragProxy.onClick);
|
455 |
+
}
|
456 |
+
}
|
457 |
+
};
|
458 |
+
Object.Event.extend(Control.Selection);
|
459 |
+
Object.Event.extend(Control.Selection.DragProxy);
|
js/livepipe/selectmultiple.js
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/rating
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global Prototype, Class, Option, $, $A, Control, $break, */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.SelectMultiple requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.SelectMultiple requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.SelectMultiple = Class.create({
|
18 |
+
select: false,
|
19 |
+
container: false,
|
20 |
+
numberOfCheckedBoxes: 0,
|
21 |
+
checkboxes: [],
|
22 |
+
hasExtraOption: false,
|
23 |
+
initialize: function(select,container,options){
|
24 |
+
this.options = {
|
25 |
+
checkboxSelector: 'input[type=checkbox]',
|
26 |
+
nameSelector: 'span.name',
|
27 |
+
labelSeparator: ', ',
|
28 |
+
valueSeparator: ',',
|
29 |
+
afterChange: Prototype.emptyFunction,
|
30 |
+
overflowString: function(str){
|
31 |
+
return str.truncate();
|
32 |
+
},
|
33 |
+
overflowLength: 30
|
34 |
+
};
|
35 |
+
Object.extend(this.options,options || {});
|
36 |
+
this.select = $(select);
|
37 |
+
this.container = $(container);
|
38 |
+
this.checkboxes = (typeof(this.options.checkboxSelector) == 'function') ?
|
39 |
+
this.options.checkboxSelector.bind(this)() :
|
40 |
+
this.container.getElementsBySelector(this.options.checkboxSelector);
|
41 |
+
var value_was_set = false;
|
42 |
+
if(this.options.value){
|
43 |
+
value_was_set = true;
|
44 |
+
this.setValue(this.options.value);
|
45 |
+
delete this.options.value;
|
46 |
+
}
|
47 |
+
this.hasExtraOption = false;
|
48 |
+
this.checkboxes.each(function(checkbox){
|
49 |
+
checkbox.observe('click',this.checkboxOnClick.bind(this,checkbox));
|
50 |
+
}.bind(this));
|
51 |
+
this.select.observe('change',this.selectOnChange.bind(this));
|
52 |
+
this.countAndCheckCheckBoxes();
|
53 |
+
if(!value_was_set) {
|
54 |
+
this.scanCheckBoxes(); }
|
55 |
+
this.notify('afterChange',this.select.options[this.select.options.selectedIndex].value);
|
56 |
+
},
|
57 |
+
countAndCheckCheckBoxes: function(){
|
58 |
+
this.numberOfCheckedBoxes = this.checkboxes.inject(0,function(number,checkbox){
|
59 |
+
checkbox.checked = (this.select.options[this.select.options.selectedIndex].value == checkbox.value);
|
60 |
+
var value_string = this.select.options[this.select.options.selectedIndex].value;
|
61 |
+
var value_collection = $A(value_string.split ? value_string.split(this.options.valueSeparator) : value_string);
|
62 |
+
var should_check = value_collection.any(function(value) {
|
63 |
+
if (!should_check && checkbox.value == value) {
|
64 |
+
return true; }
|
65 |
+
}.bind(this));
|
66 |
+
checkbox.checked = should_check;
|
67 |
+
if(checkbox.checked) {
|
68 |
+
++number; }
|
69 |
+
return number;
|
70 |
+
}.bind(this));
|
71 |
+
},
|
72 |
+
setValue: function(value_string){
|
73 |
+
this.numberOfCheckedBoxes = 0;
|
74 |
+
var value_collection = $A(value_string.split ? value_string.split(this.options.valueSeparator) : value_string);
|
75 |
+
this.checkboxes.each(function(checkbox){
|
76 |
+
checkbox.checked = false;
|
77 |
+
value_collection.each(function(value){
|
78 |
+
if(checkbox.value == value){
|
79 |
+
++this.numberOfCheckedBoxes;
|
80 |
+
checkbox.checked = true;
|
81 |
+
}
|
82 |
+
}.bind(this));
|
83 |
+
}.bind(this));
|
84 |
+
this.scanCheckBoxes();
|
85 |
+
},
|
86 |
+
selectOnChange: function(){
|
87 |
+
this.removeExtraOption();
|
88 |
+
this.countAndCheckCheckBoxes();
|
89 |
+
this.notify('afterChange',this.select.options[this.select.options.selectedIndex].value);
|
90 |
+
},
|
91 |
+
checkboxOnClick: function(checkbox){
|
92 |
+
this.numberOfCheckedBoxes = this.checkboxes.findAll(function (c) {
|
93 |
+
return c.checked;
|
94 |
+
}).length;
|
95 |
+
this.scanCheckBoxes();
|
96 |
+
this.notify('afterChange', this.numberOfCheckedBoxes === 0 ? "" :
|
97 |
+
this.select.options[this.select.options.selectedIndex].value);
|
98 |
+
},
|
99 |
+
scanCheckBoxes: function(){
|
100 |
+
switch(this.numberOfCheckedBoxes){
|
101 |
+
case 1:
|
102 |
+
this.checkboxes.each(function(checkbox){
|
103 |
+
if(checkbox.checked){
|
104 |
+
$A(this.select.options).each(function(option,i){
|
105 |
+
if(option.value == checkbox.value){
|
106 |
+
this.select.options.selectedIndex = i;
|
107 |
+
throw $break;
|
108 |
+
}
|
109 |
+
}.bind(this));
|
110 |
+
throw $break;
|
111 |
+
}
|
112 |
+
}.bind(this));
|
113 |
+
break;
|
114 |
+
case 0:
|
115 |
+
this.removeExtraOption();
|
116 |
+
break;
|
117 |
+
default:
|
118 |
+
this.addExtraOption();
|
119 |
+
break;
|
120 |
+
}
|
121 |
+
},
|
122 |
+
getLabelForExtraOption: function(){
|
123 |
+
var label = (typeof(this.options.nameSelector) == 'function' ?
|
124 |
+
this.options.nameSelector.bind(this)() :
|
125 |
+
this.container.getElementsBySelector(this.options.nameSelector).inject([],function(labels,name_element,i){
|
126 |
+
if(this.checkboxes[i].checked) {
|
127 |
+
labels.push(name_element.innerHTML); }
|
128 |
+
return labels;
|
129 |
+
}.bind(this))
|
130 |
+
).join(this.options.labelSeparator);
|
131 |
+
return (label.length >= this.options.overflowLength && this.options.overflowLength > 0) ?
|
132 |
+
(typeof(this.options.overflowString) == 'function' ? this.options.overflowString(label) : this.options.overflowString) :
|
133 |
+
label;
|
134 |
+
},
|
135 |
+
getValueForExtraOption: function(){
|
136 |
+
return this.checkboxes.inject([],function(values,checkbox){
|
137 |
+
if(checkbox.checked) {
|
138 |
+
values.push(checkbox.value); }
|
139 |
+
return values;
|
140 |
+
}).join(this.options.valueSeparator);
|
141 |
+
},
|
142 |
+
addExtraOption: function(){
|
143 |
+
this.removeExtraOption();
|
144 |
+
this.hasExtraOption = true;
|
145 |
+
this.select.options[this.select.options.length] = new Option(this.getLabelForExtraOption(),this.getValueForExtraOption());
|
146 |
+
this.select.options.selectedIndex = this.select.options.length - 1;
|
147 |
+
},
|
148 |
+
removeExtraOption: function(){
|
149 |
+
if(this.hasExtraOption){
|
150 |
+
this.select.remove(this.select.options.length - 1);
|
151 |
+
this.hasExtraOption = false;
|
152 |
+
}
|
153 |
+
}
|
154 |
+
});
|
155 |
+
Object.Event.extend(Control.SelectMultiple);
|
js/livepipe/tabs.js
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/tabs
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global window, document, Prototype, $, $A, $H, $break, Class, Element, Event, Control */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.Tabs requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.Tabs requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.Tabs = Class.create({
|
18 |
+
initialize: function(tab_list_container,options){
|
19 |
+
if(!$(tab_list_container)) {
|
20 |
+
throw "Control.Tabs could not find the element: " + tab_list_container; }
|
21 |
+
this.activeContainer = false;
|
22 |
+
this.activeLink = false;
|
23 |
+
this.containers = $H({});
|
24 |
+
this.links = [];
|
25 |
+
this.options = {
|
26 |
+
beforeChange: Prototype.emptyFunction,
|
27 |
+
afterChange: Prototype.emptyFunction,
|
28 |
+
hover: false,
|
29 |
+
tracked: true,
|
30 |
+
linkSelector: 'li a',
|
31 |
+
linkAttribute: 'href',
|
32 |
+
setClassOnContainer: false,
|
33 |
+
activeClassName: 'active',
|
34 |
+
disabledClassName: 'disabled',
|
35 |
+
defaultTab: 'first',
|
36 |
+
autoLinkExternal: true,
|
37 |
+
targetRegExp: /#(.+)$/,
|
38 |
+
showFunction: Element.show,
|
39 |
+
hideFunction: Element.hide
|
40 |
+
};
|
41 |
+
Object.extend(this.options,options || {});
|
42 |
+
if (this.options.tracked) {
|
43 |
+
Control.Tabs.instances.push(this);
|
44 |
+
}
|
45 |
+
var filterLinks;
|
46 |
+
switch (this.options.linkAttribute) {
|
47 |
+
case 'href':
|
48 |
+
case 'src':
|
49 |
+
filterLinks = function(link){
|
50 |
+
return (/^#/).test(link.getAttribute(this.options.linkAttribute).replace(
|
51 |
+
window.location.href.split('#')[0],''));
|
52 |
+
};
|
53 |
+
break;
|
54 |
+
|
55 |
+
default:
|
56 |
+
if (typeof(this.options.linkAttribute) == 'function') {
|
57 |
+
filterLinks = this.options.linkAttribute;
|
58 |
+
}
|
59 |
+
else {
|
60 |
+
filterLinks = function(link) {
|
61 |
+
return link.hasAttribute(this.options.linkAttribute);
|
62 |
+
};
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
(typeof(this.options.linkSelector) == 'string' ?
|
67 |
+
$(tab_list_container).select(this.options.linkSelector) :
|
68 |
+
this.options.linkSelector($(tab_list_container))
|
69 |
+
).findAll(filterLinks.bind(this)).each(function(link){
|
70 |
+
this.addTab(link);
|
71 |
+
}.bind(this));
|
72 |
+
this.containers.values().each(Element.hide);
|
73 |
+
if(this.options.defaultTab == 'first') {
|
74 |
+
this.setActiveTab(this.links.first());
|
75 |
+
} else if(this.options.defaultTab == 'last') {
|
76 |
+
this.setActiveTab(this.links.last());
|
77 |
+
} else {
|
78 |
+
this.setActiveTab(this.options.defaultTab); }
|
79 |
+
var targets = this.options.targetRegExp.exec(window.location);
|
80 |
+
if(targets && targets[1]){
|
81 |
+
targets[1].split(',').each(function(target){
|
82 |
+
this.setActiveTab(this.links.find(function(link){
|
83 |
+
return link.key == target;
|
84 |
+
}));
|
85 |
+
}.bind(this));
|
86 |
+
}
|
87 |
+
if(this.options.autoLinkExternal){
|
88 |
+
$A(document.getElementsByTagName('a')).each(function(a){
|
89 |
+
if(!this.links.include(a)){
|
90 |
+
var clean_href = a.href.replace(window.location.href.split('#')[0],'');
|
91 |
+
if(clean_href.substring(0,1) == '#'){
|
92 |
+
if(this.containers.keys().include(clean_href.substring(1))){
|
93 |
+
$(a).observe('click',function(event,clean_href){
|
94 |
+
this.setActiveTab(clean_href.substring(1));
|
95 |
+
}.bindAsEventListener(this,clean_href));
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}.bind(this));
|
100 |
+
}
|
101 |
+
},
|
102 |
+
addTab: function(link){
|
103 |
+
this.links.push(link);
|
104 |
+
|
105 |
+
switch (this.options.linkAttribute) {
|
106 |
+
case 'href':
|
107 |
+
case 'src':
|
108 |
+
link.key = link.getAttribute(this.options.linkAttribute).replace(
|
109 |
+
window.location.href.split('#')[0],'').split('#').last().replace(/#/,'');
|
110 |
+
break;
|
111 |
+
|
112 |
+
default:
|
113 |
+
if (typeof(this.options.linkAttribute) == 'function') {
|
114 |
+
link.key = this.options.linkAttribute(link);
|
115 |
+
}
|
116 |
+
else {
|
117 |
+
link.key = link.getAttribute(this.options.linkAttribute);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
var container = this.options.tabs_container ? this.options.tabs_container.down('#'+link.key) : $(link.key);
|
121 |
+
if(!container) {
|
122 |
+
throw "Control.Tabs: #" + link.key + " was not found on the page."; }
|
123 |
+
this.containers.set(link.key,container);
|
124 |
+
link[this.options.hover ? 'onmouseover' : 'onclick'] = function(link){
|
125 |
+
if(window.event) {
|
126 |
+
Event.stop(window.event); }
|
127 |
+
this.setActiveTab(link);
|
128 |
+
return false;
|
129 |
+
}.bind(this,link);
|
130 |
+
},
|
131 |
+
getTab: function (link) {
|
132 |
+
if(!link && typeof(link) == 'undefined') {
|
133 |
+
return null; }
|
134 |
+
if(typeof(link) == 'string'){
|
135 |
+
return this.getTab(this.links.find(function(_link){
|
136 |
+
return _link.key == link;
|
137 |
+
}));
|
138 |
+
}else if(typeof(link) == 'number'){
|
139 |
+
return this.getTab(this.links[link]);
|
140 |
+
}else {
|
141 |
+
return this.containers.get(link.key);
|
142 |
+
}
|
143 |
+
},
|
144 |
+
setActiveTab: function(link){
|
145 |
+
if(!link && typeof(link) == 'undefined') {
|
146 |
+
return; }
|
147 |
+
if(typeof(link) == 'string'){
|
148 |
+
this.setActiveTab(this.links.find(function(_link){
|
149 |
+
return _link.key == link;
|
150 |
+
}));
|
151 |
+
}else if(typeof(link) == 'number'){
|
152 |
+
this.setActiveTab(this.links[link]);
|
153 |
+
}else if(!(this.options.setClassOnContainer ? $(link.parentNode) : link).hasClassName(this.options.disabledClassName)){
|
154 |
+
if(link == this.activeLink) {
|
155 |
+
return; }
|
156 |
+
if(this.notify('beforeChange',this.activeContainer,this.containers.get(link.key)) === false) {
|
157 |
+
return; }
|
158 |
+
if(this.activeContainer) {
|
159 |
+
this.options.hideFunction(this.activeContainer); }
|
160 |
+
this.links.each(function(item){
|
161 |
+
(this.options.setClassOnContainer ? $(item.parentNode) : item).removeClassName(this.options.activeClassName);
|
162 |
+
}.bind(this));
|
163 |
+
(this.options.setClassOnContainer ? $(link.parentNode) : link).addClassName(this.options.activeClassName);
|
164 |
+
this.activeContainer = this.containers.get(link.key);
|
165 |
+
this.activeLink = link;
|
166 |
+
this.options.showFunction(this.containers.get(link.key));
|
167 |
+
this.notify('afterChange',this.containers.get(link.key));
|
168 |
+
}
|
169 |
+
},
|
170 |
+
disableTab: function (link) {
|
171 |
+
if(!link && typeof(link) == 'undefined') {
|
172 |
+
return; }
|
173 |
+
if(typeof(link) == 'string'){
|
174 |
+
this.disableTab(this.links.find(function(_link){
|
175 |
+
return _link.key == link;
|
176 |
+
}));
|
177 |
+
}else if(typeof(link) == 'number'){
|
178 |
+
this.disableTab(this.links[link]);
|
179 |
+
}else{
|
180 |
+
if ({'INPUT':true,'BUTTON':true,'SELECT':true,'TEXTAREA':true}[link.nodeName]) {
|
181 |
+
link.disabled = true; }
|
182 |
+
(this.options.setClassOnContainer ? $(link.parentNode) : link).addClassName(this.options.disabledClassName);
|
183 |
+
}
|
184 |
+
},
|
185 |
+
enableTab: function (link) {
|
186 |
+
if(!link && typeof(link) == 'undefined') {
|
187 |
+
return; }
|
188 |
+
if(typeof(link) == 'string'){
|
189 |
+
this.enableTab(this.links.find(function(_link){
|
190 |
+
return _link.key == link;
|
191 |
+
}));
|
192 |
+
}else if(typeof(link) == 'number'){
|
193 |
+
this.enableTab(this.links[link]);
|
194 |
+
}else{
|
195 |
+
if ({'INPUT':true,'BUTTON':true,'SELECT':true,'TEXTAREA':true}[link.nodeName]) {
|
196 |
+
link.disabled = false; }
|
197 |
+
(this.options.setClassOnContainer ? $(link.parentNode) : link).removeClassName(this.options.disabledClassName);
|
198 |
+
}
|
199 |
+
},
|
200 |
+
next: function(){
|
201 |
+
this.links.each(function(link,i){
|
202 |
+
if(this.activeLink == link && this.links[i + 1]){
|
203 |
+
this.setActiveTab(this.links[i + 1]);
|
204 |
+
throw $break;
|
205 |
+
}
|
206 |
+
}.bind(this));
|
207 |
+
},
|
208 |
+
previous: function(){
|
209 |
+
this.links.each(function(link,i){
|
210 |
+
if(this.activeLink == link && this.links[i - 1]){
|
211 |
+
this.setActiveTab(this.links[i - 1]);
|
212 |
+
throw $break;
|
213 |
+
}
|
214 |
+
}.bind(this));
|
215 |
+
},
|
216 |
+
first: function(){
|
217 |
+
this.setActiveTab(this.links.first());
|
218 |
+
},
|
219 |
+
last: function(){
|
220 |
+
this.setActiveTab(this.links.last());
|
221 |
+
}
|
222 |
+
});
|
223 |
+
Object.extend(Control.Tabs,{
|
224 |
+
instances: [],
|
225 |
+
findByTabId: function(id){
|
226 |
+
return Control.Tabs.instances.find(function(tab){
|
227 |
+
return tab.links.find(function(link){
|
228 |
+
return link.key == id;
|
229 |
+
});
|
230 |
+
});
|
231 |
+
}
|
232 |
+
});
|
233 |
+
Object.Event.extend(Control.Tabs);
|
js/livepipe/textarea.js
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/textarea
|
7 |
+
* @require prototype.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
/*global window, document, Prototype, Class, $, $A, Control */
|
11 |
+
|
12 |
+
if(typeof(Prototype) == "undefined") {
|
13 |
+
throw "Control.TextArea requires Prototype to be loaded."; }
|
14 |
+
if(typeof(Object.Event) == "undefined") {
|
15 |
+
throw "Control.TextArea requires Object.Event to be loaded."; }
|
16 |
+
|
17 |
+
Control.TextArea = Class.create({
|
18 |
+
initialize: function(textarea){
|
19 |
+
this.onChangeTimeout = false;
|
20 |
+
this.element = $(textarea);
|
21 |
+
$(this.element).observe('keyup',this.doOnChange.bindAsEventListener(this));
|
22 |
+
$(this.element).observe('paste',this.doOnChange.bindAsEventListener(this));
|
23 |
+
$(this.element).observe('input',this.doOnChange.bindAsEventListener(this));
|
24 |
+
if(!!document.selection){
|
25 |
+
$(this.element).observe('mouseup',this.saveRange.bindAsEventListener(this));
|
26 |
+
$(this.element).observe('keyup',this.saveRange.bindAsEventListener(this));
|
27 |
+
}
|
28 |
+
},
|
29 |
+
doOnChange: function(event){
|
30 |
+
if(this.onChangeTimeout) {
|
31 |
+
window.clearTimeout(this.onChangeTimeout); }
|
32 |
+
this.onChangeTimeout = window.setTimeout(function(){
|
33 |
+
this.notify('change',this.getValue());
|
34 |
+
}.bind(this),Control.TextArea.onChangeTimeoutLength);
|
35 |
+
},
|
36 |
+
saveRange: function(){
|
37 |
+
this.range = document.selection.createRange();
|
38 |
+
},
|
39 |
+
getValue: function(){
|
40 |
+
return this.element.value;
|
41 |
+
},
|
42 |
+
getSelection: function(){
|
43 |
+
if(!!document.selection) {
|
44 |
+
return document.selection.createRange().text; }
|
45 |
+
else if(!!this.element.setSelectionRange) {
|
46 |
+
return this.element.value.substring(this.element.selectionStart,this.element.selectionEnd); }
|
47 |
+
else {
|
48 |
+
return false; }
|
49 |
+
},
|
50 |
+
replaceSelection: function(text){
|
51 |
+
var scroll_top = this.element.scrollTop;
|
52 |
+
if(!!document.selection){
|
53 |
+
this.element.focus();
|
54 |
+
var range = (this.range) ? this.range : document.selection.createRange();
|
55 |
+
range.text = text;
|
56 |
+
range.select();
|
57 |
+
}else if(!!this.element.setSelectionRange){
|
58 |
+
var selection_start = this.element.selectionStart;
|
59 |
+
this.element.value = this.element.value.substring(0,selection_start) + text + this.element.value.substring(this.element.selectionEnd);
|
60 |
+
this.element.setSelectionRange(selection_start + text.length,selection_start + text.length);
|
61 |
+
}
|
62 |
+
this.doOnChange();
|
63 |
+
this.element.focus();
|
64 |
+
this.element.scrollTop = scroll_top;
|
65 |
+
},
|
66 |
+
wrapSelection: function(before,after){
|
67 |
+
var sel = this.getSelection();
|
68 |
+
// Remove the wrapping if the selection has the same before/after
|
69 |
+
if (sel.indexOf(before) === 0 &&
|
70 |
+
sel.lastIndexOf(after) === (sel.length - after.length)) {
|
71 |
+
this.replaceSelection(sel.substring(before.length,
|
72 |
+
sel.length - after.length));
|
73 |
+
} else { this.replaceSelection(before + sel + after); }
|
74 |
+
},
|
75 |
+
insertBeforeSelection: function(text){
|
76 |
+
this.replaceSelection(text + this.getSelection());
|
77 |
+
},
|
78 |
+
insertAfterSelection: function(text){
|
79 |
+
this.replaceSelection(this.getSelection() + text);
|
80 |
+
},
|
81 |
+
collectFromEachSelectedLine: function(callback,before,after){
|
82 |
+
this.replaceSelection((before || '') + $A(this.getSelection().split("\n")).collect(callback).join("\n") + (after || ''));
|
83 |
+
},
|
84 |
+
insertBeforeEachSelectedLine: function(text,before,after){
|
85 |
+
this.collectFromEachSelectedLine(function(line){
|
86 |
+
},before,after);
|
87 |
+
}
|
88 |
+
});
|
89 |
+
Object.extend(Control.TextArea,{
|
90 |
+
onChangeTimeoutLength: 500
|
91 |
+
});
|
92 |
+
Object.Event.extend(Control.TextArea);
|
93 |
+
|
94 |
+
Control.TextArea.ToolBar = Class.create( {
|
95 |
+
initialize: function(textarea,toolbar){
|
96 |
+
this.textarea = textarea;
|
97 |
+
if(toolbar) {
|
98 |
+
this.container = $(toolbar); }
|
99 |
+
else{
|
100 |
+
this.container = $(document.createElement('ul'));
|
101 |
+
this.textarea.element.parentNode.insertBefore(this.container,this.textarea.element);
|
102 |
+
}
|
103 |
+
},
|
104 |
+
attachButton: function(node,callback){
|
105 |
+
node.onclick = function(){return false;};
|
106 |
+
$(node).observe('click',callback.bindAsEventListener(this.textarea));
|
107 |
+
},
|
108 |
+
addButton: function(link_text,callback,attrs){
|
109 |
+
var li = document.createElement('li');
|
110 |
+
var a = document.createElement('a');
|
111 |
+
a.href = '#';
|
112 |
+
this.attachButton(a,callback);
|
113 |
+
li.appendChild(a);
|
114 |
+
Object.extend(a,attrs || {});
|
115 |
+
if(link_text){
|
116 |
+
var span = document.createElement('span');
|
117 |
+
span.innerHTML = link_text;
|
118 |
+
a.appendChild(span);
|
119 |
+
}
|
120 |
+
this.container.appendChild(li);
|
121 |
+
}
|
122 |
+
});
|
js/livepipe/window.js
ADDED
@@ -0,0 +1,947 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @author Ryan Johnson <http://syntacticx.com/>
|
3 |
+
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
|
4 |
+
* @package LivePipe UI
|
5 |
+
* @license MIT
|
6 |
+
* @url http://livepipe.net/control/window
|
7 |
+
* @require prototype.js, effects.js, draggable.js, resizable.js, livepipe.js
|
8 |
+
*/
|
9 |
+
|
10 |
+
//adds onDraw and constrainToViewport option to draggable
|
11 |
+
if(typeof(Draggable) != 'undefined'){
|
12 |
+
//allows the point to be modified with an onDraw callback
|
13 |
+
Draggable.prototype.draw = function(point) {
|
14 |
+
var pos = Position.cumulativeOffset(this.element);
|
15 |
+
if(this.options.ghosting) {
|
16 |
+
var r = Position.realOffset(this.element);
|
17 |
+
pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
|
18 |
+
}
|
19 |
+
|
20 |
+
var d = this.currentDelta();
|
21 |
+
pos[0] -= d[0]; pos[1] -= d[1];
|
22 |
+
|
23 |
+
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
|
24 |
+
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
|
25 |
+
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
|
26 |
+
}
|
27 |
+
|
28 |
+
var p = [0,1].map(function(i){
|
29 |
+
return (point[i]-pos[i]-this.offset[i])
|
30 |
+
}.bind(this));
|
31 |
+
|
32 |
+
if(this.options.snap) {
|
33 |
+
if(typeof this.options.snap == 'function') {
|
34 |
+
p = this.options.snap(p[0],p[1],this);
|
35 |
+
} else {
|
36 |
+
if(this.options.snap instanceof Array) {
|
37 |
+
p = p.map( function(v, i) {return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
|
38 |
+
} else {
|
39 |
+
p = p.map( function(v) {return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
if(this.options.onDraw)
|
45 |
+
this.options.onDraw.bind(this)(p);
|
46 |
+
else{
|
47 |
+
var style = this.element.style;
|
48 |
+
if(this.options.constrainToViewport){
|
49 |
+
var viewport_dimensions = document.viewport.getDimensions();
|
50 |
+
var container_dimensions = this.element.getDimensions();
|
51 |
+
var margin_top = parseInt(this.element.getStyle('margin-top'));
|
52 |
+
var margin_left = parseInt(this.element.getStyle('margin-left'));
|
53 |
+
var boundary = [[
|
54 |
+
0 - margin_left,
|
55 |
+
0 - margin_top
|
56 |
+
],[
|
57 |
+
(viewport_dimensions.width - container_dimensions.width) - margin_left,
|
58 |
+
(viewport_dimensions.height - container_dimensions.height) - margin_top
|
59 |
+
]];
|
60 |
+
if((!this.options.constraint) || (this.options.constraint=='horizontal')){
|
61 |
+
if((p[0] >= boundary[0][0]) && (p[0] <= boundary[1][0]))
|
62 |
+
this.element.style.left = p[0] + "px";
|
63 |
+
else
|
64 |
+
this.element.style.left = ((p[0] < boundary[0][0]) ? boundary[0][0] : boundary[1][0]) + "px";
|
65 |
+
}
|
66 |
+
if((!this.options.constraint) || (this.options.constraint=='vertical')){
|
67 |
+
if((p[1] >= boundary[0][1] ) && (p[1] <= boundary[1][1]))
|
68 |
+
this.element.style.top = p[1] + "px";
|
69 |
+
else
|
70 |
+
this.element.style.top = ((p[1] <= boundary[0][1]) ? boundary[0][1] : boundary[1][1]) + "px";
|
71 |
+
}
|
72 |
+
}else{
|
73 |
+
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
|
74 |
+
style.left = p[0] + "px";
|
75 |
+
if((!this.options.constraint) || (this.options.constraint=='vertical'))
|
76 |
+
style.top = p[1] + "px";
|
77 |
+
}
|
78 |
+
if(style.visibility=="hidden")
|
79 |
+
style.visibility = ""; // fix gecko rendering
|
80 |
+
}
|
81 |
+
};
|
82 |
+
}
|
83 |
+
|
84 |
+
if(typeof(Prototype) == "undefined")
|
85 |
+
throw "Control.Window requires Prototype to be loaded.";
|
86 |
+
if(typeof(IframeShim) == "undefined")
|
87 |
+
throw "Control.Window requires IframeShim to be loaded.";
|
88 |
+
if(typeof(Object.Event) == "undefined")
|
89 |
+
throw "Control.Window requires Object.Event to be loaded.";
|
90 |
+
/*
|
91 |
+
known issues:
|
92 |
+
- when iframe is clicked is does not gain focus
|
93 |
+
- safari can't open multiple iframes properly
|
94 |
+
- constrainToViewport: body must have no margin or padding for this to work properly
|
95 |
+
- iframe will be mis positioned during fade in
|
96 |
+
- document.viewport does not account for scrollbars (this will eventually be fixed in the prototype core)
|
97 |
+
notes
|
98 |
+
- setting constrainToViewport only works when the page is not scrollable
|
99 |
+
- setting draggable: true will negate the effects of position: center
|
100 |
+
*/
|
101 |
+
Control.Window = Class.create({
|
102 |
+
initialize: function(container,options){
|
103 |
+
Control.Window.windows.push(this);
|
104 |
+
|
105 |
+
//attribute initialization
|
106 |
+
this.container = false;
|
107 |
+
this.isOpen = false;
|
108 |
+
this.href = false;
|
109 |
+
this.sourceContainer = false; //this is optionally the container that will open the window
|
110 |
+
this.ajaxRequest = false;
|
111 |
+
this.remoteContentLoaded = false; //this is set when the code to load the remote content is run, onRemoteContentLoaded is fired when the connection is closed
|
112 |
+
this.numberInSequence = Control.Window.windows.length + 1; //only useful for the effect scoping
|
113 |
+
this.indicator = false;
|
114 |
+
this.effects = {
|
115 |
+
fade: false,
|
116 |
+
appear: false
|
117 |
+
};
|
118 |
+
this.indicatorEffects = {
|
119 |
+
fade: false,
|
120 |
+
appear: false
|
121 |
+
};
|
122 |
+
|
123 |
+
//options
|
124 |
+
this.options = Object.extend({
|
125 |
+
//lifecycle
|
126 |
+
beforeOpen: Prototype.emptyFunction,
|
127 |
+
afterOpen: Prototype.emptyFunction,
|
128 |
+
beforeClose: Prototype.emptyFunction,
|
129 |
+
afterClose: Prototype.emptyFunction,
|
130 |
+
//dimensions and modes
|
131 |
+
height: null,
|
132 |
+
width: null,
|
133 |
+
className: false,
|
134 |
+
position: 'center', //'center', 'center_once', 'relative', [x,y], [function(){return x;},function(){return y;}]
|
135 |
+
offsetLeft: 0, //available only for anchors opening the window, or windows set to position: hover
|
136 |
+
offsetTop: 0, //""
|
137 |
+
iframe: false, //if the window has an href, this will display the href as an iframe instead of requesting the url as an an Ajax.Request
|
138 |
+
hover: false, //element object to hover over, or if "true" only available for windows with sourceContainer (an anchor or any element already on the page with an href attribute)
|
139 |
+
indicator: false, //element to show or hide when ajax requests, images and iframes are loading
|
140 |
+
closeOnClick: false, //does not work with hover,can be: true (click anywhere), 'container' (will refer to this.container), or element (a specific element)
|
141 |
+
iframeshim: true, //whether or not to position an iFrameShim underneath the window
|
142 |
+
//effects
|
143 |
+
fade: false,
|
144 |
+
fadeDuration: 0.75,
|
145 |
+
//draggable
|
146 |
+
draggable: false,
|
147 |
+
onDrag: Prototype.emptyFunction,
|
148 |
+
//resizable
|
149 |
+
resizable: false,
|
150 |
+
minHeight: false,
|
151 |
+
minWidth: false,
|
152 |
+
maxHeight: false,
|
153 |
+
maxWidth: false,
|
154 |
+
onResize: Prototype.emptyFunction,
|
155 |
+
//draggable and resizable
|
156 |
+
constrainToViewport: false,
|
157 |
+
//ajax
|
158 |
+
method: 'post',
|
159 |
+
parameters: {},
|
160 |
+
onComplete: Prototype.emptyFunction,
|
161 |
+
onSuccess: Prototype.emptyFunction,
|
162 |
+
onFailure: Prototype.emptyFunction,
|
163 |
+
onException: Prototype.emptyFunction,
|
164 |
+
//any element with an href (image,iframe,ajax) will call this after it is done loading
|
165 |
+
onRemoteContentLoaded: Prototype.emptyFunction,
|
166 |
+
insertRemoteContentAt: false //false will set this to this.container, can be string selector (first returned will be selected), or an Element that must be a child of this.container
|
167 |
+
},options || {});
|
168 |
+
|
169 |
+
//container setup
|
170 |
+
this.indicator = this.options.indicator ? $(this.options.indicator) : false;
|
171 |
+
if(container){
|
172 |
+
if(typeof(container) == "string" && container.match(Control.Window.uriRegex))
|
173 |
+
this.href = container;
|
174 |
+
else{
|
175 |
+
this.container = $(container);
|
176 |
+
//need to create the container now for tooltips (or hover: element with no container already on the page)
|
177 |
+
//second call made below will not create the container since the check is done inside createDefaultContainer()
|
178 |
+
this.createDefaultContainer(container);
|
179 |
+
//if an element with an href was passed in we use it to activate the window
|
180 |
+
if(this.container && ((this.container.readAttribute('href') && this.container.readAttribute('href') != '') || (this.options.hover && this.options.hover !== true))){
|
181 |
+
if(this.options.hover && this.options.hover !== true)
|
182 |
+
this.sourceContainer = $(this.options.hover);
|
183 |
+
else{
|
184 |
+
this.sourceContainer = this.container;
|
185 |
+
this.href = this.container.readAttribute('href');
|
186 |
+
var rel = this.href.match(/^#(.+)$/);
|
187 |
+
if(rel && rel[1]){
|
188 |
+
this.container = $(rel[1]);
|
189 |
+
this.href = false;
|
190 |
+
}else
|
191 |
+
this.container = false;
|
192 |
+
}
|
193 |
+
//hover or click handling
|
194 |
+
this.sourceContainerOpenHandler = function(event){
|
195 |
+
this.open(event);
|
196 |
+
event.stop();
|
197 |
+
return false;
|
198 |
+
}.bindAsEventListener(this);
|
199 |
+
this.sourceContainerCloseHandler = function(event){
|
200 |
+
this.close(event);
|
201 |
+
}.bindAsEventListener(this);
|
202 |
+
this.sourceContainerMouseMoveHandler = function(event){
|
203 |
+
this.position(event);
|
204 |
+
}.bindAsEventListener(this);
|
205 |
+
if(this.options.hover){
|
206 |
+
this.sourceContainer.observe('mouseenter',this.sourceContainerOpenHandler);
|
207 |
+
this.sourceContainer.observe('mouseleave',this.sourceContainerCloseHandler);
|
208 |
+
if(this.options.position == 'mouse')
|
209 |
+
this.sourceContainer.observe('mousemove',this.sourceContainerMouseMoveHandler);
|
210 |
+
}else
|
211 |
+
this.sourceContainer.observe('click',this.sourceContainerOpenHandler);
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
this.createDefaultContainer(container);
|
216 |
+
if(this.options.insertRemoteContentAt === false)
|
217 |
+
this.options.insertRemoteContentAt = this.container;
|
218 |
+
var styles = {
|
219 |
+
margin: 0,
|
220 |
+
position: 'absolute',
|
221 |
+
zIndex: Control.Window.initialZIndexForWindow()
|
222 |
+
};
|
223 |
+
if(this.options.width)
|
224 |
+
styles.width = $value(this.options.width) + 'px';
|
225 |
+
if(this.options.height)
|
226 |
+
styles.height = $value(this.options.height) + 'px';
|
227 |
+
this.container.setStyle(styles);
|
228 |
+
if(this.options.className)
|
229 |
+
this.container.addClassName(this.options.className);
|
230 |
+
this.positionHandler = this.position.bindAsEventListener(this);
|
231 |
+
this.outOfBoundsPositionHandler = this.ensureInBounds.bindAsEventListener(this);
|
232 |
+
this.bringToFrontHandler = this.bringToFront.bindAsEventListener(this);
|
233 |
+
this.container.observe('mousedown',this.bringToFrontHandler);
|
234 |
+
this.container.hide();
|
235 |
+
this.closeHandler = this.close.bindAsEventListener(this);
|
236 |
+
//iframeshim setup
|
237 |
+
if(this.options.iframeshim){
|
238 |
+
this.iFrameShim = new IframeShim();
|
239 |
+
this.iFrameShim.hide();
|
240 |
+
}
|
241 |
+
//resizable support
|
242 |
+
this.applyResizable();
|
243 |
+
//draggable support
|
244 |
+
this.applyDraggable();
|
245 |
+
|
246 |
+
//makes sure the window can't go out of bounds
|
247 |
+
Event.observe(window,'resize',this.outOfBoundsPositionHandler);
|
248 |
+
|
249 |
+
this.notify('afterInitialize');
|
250 |
+
},
|
251 |
+
open: function(event){
|
252 |
+
if(this.isOpen){
|
253 |
+
this.bringToFront();
|
254 |
+
return false;
|
255 |
+
}
|
256 |
+
if(this.notify('beforeOpen') === false)
|
257 |
+
return false;
|
258 |
+
//closeOnClick
|
259 |
+
if(this.options.closeOnClick){
|
260 |
+
if(this.options.closeOnClick === true)
|
261 |
+
this.closeOnClickContainer = $(document.body);
|
262 |
+
else if(this.options.closeOnClick == 'container')
|
263 |
+
this.closeOnClickContainer = this.container;
|
264 |
+
else if (this.options.closeOnClick == 'overlay'){
|
265 |
+
Control.Overlay.load();
|
266 |
+
this.closeOnClickContainer = Control.Overlay.container;
|
267 |
+
}else
|
268 |
+
this.closeOnClickContainer = $(this.options.closeOnClick);
|
269 |
+
this.closeOnClickContainer.observe('click',this.closeHandler);
|
270 |
+
}
|
271 |
+
if(this.href && !this.options.iframe && !this.remoteContentLoaded){
|
272 |
+
//link to image
|
273 |
+
this.remoteContentLoaded = true;
|
274 |
+
if(this.href.match(/\.(jpe?g|gif|png|tiff?)$/i)){
|
275 |
+
var img = new Element('img');
|
276 |
+
img.observe('load',function(img){
|
277 |
+
this.getRemoteContentInsertionTarget().insert(img);
|
278 |
+
this.position();
|
279 |
+
if(this.notify('onRemoteContentLoaded') !== false){
|
280 |
+
if(this.options.indicator)
|
281 |
+
this.hideIndicator();
|
282 |
+
this.finishOpen();
|
283 |
+
}
|
284 |
+
}.bind(this,img));
|
285 |
+
img.writeAttribute('src',this.href);
|
286 |
+
}else{
|
287 |
+
//if this is an ajax window it will only open if the request is successful
|
288 |
+
if(!this.ajaxRequest){
|
289 |
+
if(this.options.indicator)
|
290 |
+
this.showIndicator();
|
291 |
+
this.ajaxRequest = new Ajax.Request(this.href,{
|
292 |
+
method: this.options.method,
|
293 |
+
parameters: this.options.parameters,
|
294 |
+
onComplete: function(request){
|
295 |
+
this.notify('onComplete',request);
|
296 |
+
this.ajaxRequest = false;
|
297 |
+
}.bind(this),
|
298 |
+
onSuccess: function(request){
|
299 |
+
this.getRemoteContentInsertionTarget().insert(request.responseText);
|
300 |
+
this.notify('onSuccess',request);
|
301 |
+
if(this.notify('onRemoteContentLoaded') !== false){
|
302 |
+
if(this.options.indicator)
|
303 |
+
this.hideIndicator();
|
304 |
+
this.finishOpen();
|
305 |
+
}
|
306 |
+
}.bind(this),
|
307 |
+
onFailure: function(request){
|
308 |
+
this.notify('onFailure',request);
|
309 |
+
if(this.options.indicator)
|
310 |
+
this.hideIndicator();
|
311 |
+
}.bind(this),
|
312 |
+
onException: function(request,e){
|
313 |
+
this.notify('onException',request,e);
|
314 |
+
if(this.options.indicator)
|
315 |
+
this.hideIndicator();
|
316 |
+
}.bind(this)
|
317 |
+
});
|
318 |
+
}
|
319 |
+
}
|
320 |
+
return true;
|
321 |
+
}else if(this.options.iframe && !this.remoteContentLoaded){
|
322 |
+
//iframe
|
323 |
+
this.remoteContentLoaded = true;
|
324 |
+
if(this.options.indicator)
|
325 |
+
this.showIndicator();
|
326 |
+
this.getRemoteContentInsertionTarget().insert(Control.Window.iframeTemplate.evaluate({
|
327 |
+
href: this.href
|
328 |
+
}));
|
329 |
+
var iframe = this.container.down('iframe');
|
330 |
+
iframe.onload = function(){
|
331 |
+
this.notify('onRemoteContentLoaded');
|
332 |
+
if(this.options.indicator)
|
333 |
+
this.hideIndicator();
|
334 |
+
iframe.onload = null;
|
335 |
+
}.bind(this);
|
336 |
+
}
|
337 |
+
this.finishOpen(event);
|
338 |
+
return true
|
339 |
+
},
|
340 |
+
close: function(event){ //event may or may not be present
|
341 |
+
if(!this.isOpen || this.notify('beforeClose',event) === false)
|
342 |
+
return false;
|
343 |
+
if(this.options.closeOnClick)
|
344 |
+
this.closeOnClickContainer.stopObserving('click',this.closeHandler);
|
345 |
+
if(this.options.fade){
|
346 |
+
this.effects.fade = new Effect.Fade(this.container,{
|
347 |
+
queue: {
|
348 |
+
position: 'front',
|
349 |
+
scope: 'Control.Window' + this.numberInSequence
|
350 |
+
},
|
351 |
+
from: 1,
|
352 |
+
to: 0,
|
353 |
+
duration: this.options.fadeDuration / 2,
|
354 |
+
afterFinish: function(){
|
355 |
+
if(this.iFrameShim)
|
356 |
+
this.iFrameShim.hide();
|
357 |
+
this.isOpen = false;
|
358 |
+
this.notify('afterClose');
|
359 |
+
}.bind(this)
|
360 |
+
});
|
361 |
+
}else{
|
362 |
+
this.container.hide();
|
363 |
+
if(this.iFrameShim)
|
364 |
+
this.iFrameShim.hide();
|
365 |
+
}
|
366 |
+
if(this.ajaxRequest)
|
367 |
+
this.ajaxRequest.transport.abort();
|
368 |
+
if(!(this.options.draggable || this.options.resizable) && this.options.position == 'center')
|
369 |
+
Event.stopObserving(window,'resize',this.positionHandler);
|
370 |
+
if(!this.options.draggable && this.options.position == 'center')
|
371 |
+
Event.stopObserving(window,'scroll',this.positionHandler);
|
372 |
+
if(this.options.indicator)
|
373 |
+
this.hideIndicator();
|
374 |
+
if(!this.options.fade){
|
375 |
+
this.isOpen = false;
|
376 |
+
this.notify('afterClose');
|
377 |
+
}
|
378 |
+
return true;
|
379 |
+
},
|
380 |
+
position: function(event){
|
381 |
+
//this is up top for performance reasons
|
382 |
+
if(this.options.position == 'mouse'){
|
383 |
+
var xy = [Event.pointerX(event),Event.pointerY(event)];
|
384 |
+
this.container.setStyle({
|
385 |
+
top: xy[1] + $value(this.options.offsetTop) + 'px',
|
386 |
+
left: xy[0] + $value(this.options.offsetLeft) + 'px'
|
387 |
+
});
|
388 |
+
return;
|
389 |
+
}
|
390 |
+
var container_dimensions = this.container.getDimensions();
|
391 |
+
var viewport_dimensions = document.viewport.getDimensions();
|
392 |
+
Position.prepare();
|
393 |
+
var offset_left = (Position.deltaX + Math.floor((viewport_dimensions.width - container_dimensions.width) / 2));
|
394 |
+
var offset_top = (Position.deltaY + ((viewport_dimensions.height > container_dimensions.height) ? Math.floor((viewport_dimensions.height - container_dimensions.height) / 2) : 0));
|
395 |
+
if(this.options.position == 'center' || this.options.position == 'center_once'){
|
396 |
+
this.container.setStyle({
|
397 |
+
top: (container_dimensions.height <= viewport_dimensions.height) ? ((offset_top != null && offset_top > 0) ? offset_top : 0) + 'px' : 0,
|
398 |
+
left: (container_dimensions.width <= viewport_dimensions.width) ? ((offset_left != null && offset_left > 0) ? offset_left : 0) + 'px' : 0
|
399 |
+
});
|
400 |
+
}else if(this.options.position == 'relative'){
|
401 |
+
var xy = this.sourceContainer.cumulativeOffset();
|
402 |
+
var top = xy[1] + $value(this.options.offsetTop);
|
403 |
+
var left = xy[0] + $value(this.options.offsetLeft);
|
404 |
+
this.container.setStyle({
|
405 |
+
top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
|
406 |
+
left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
|
407 |
+
});
|
408 |
+
}else if(this.options.position.length){
|
409 |
+
var top = $value(this.options.position[1]) + $value(this.options.offsetTop);
|
410 |
+
var left = $value(this.options.position[0]) + $value(this.options.offsetLeft);
|
411 |
+
this.container.setStyle({
|
412 |
+
top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
|
413 |
+
left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
|
414 |
+
});
|
415 |
+
}
|
416 |
+
if(this.iFrameShim)
|
417 |
+
this.updateIFrameShimZIndex();
|
418 |
+
},
|
419 |
+
ensureInBounds: function(){
|
420 |
+
if(!this.isOpen)
|
421 |
+
return;
|
422 |
+
var viewport_dimensions = document.viewport.getDimensions();
|
423 |
+
var container_offset = this.container.cumulativeOffset();
|
424 |
+
var container_dimensions = this.container.getDimensions();
|
425 |
+
if(container_offset.left + container_dimensions.width > viewport_dimensions.width){
|
426 |
+
this.container.setStyle({
|
427 |
+
left: (Math.max(0,viewport_dimensions.width - container_dimensions.width)) + 'px'
|
428 |
+
});
|
429 |
+
}
|
430 |
+
if(container_offset.top + container_dimensions.height > viewport_dimensions.height){
|
431 |
+
this.container.setStyle({
|
432 |
+
top: (Math.max(0,viewport_dimensions.height - container_dimensions.height)) + 'px'
|
433 |
+
});
|
434 |
+
}
|
435 |
+
},
|
436 |
+
bringToFront: function(){
|
437 |
+
Control.Window.bringToFront(this);
|
438 |
+
this.notify('bringToFront');
|
439 |
+
},
|
440 |
+
destroy: function(){
|
441 |
+
this.container.stopObserving('mousedown',this.bringToFrontHandler);
|
442 |
+
if(this.draggable){
|
443 |
+
Draggables.removeObserver(this.container);
|
444 |
+
this.draggable.handle.stopObserving('mousedown',this.bringToFrontHandler);
|
445 |
+
this.draggable.destroy();
|
446 |
+
}
|
447 |
+
if(this.resizable){
|
448 |
+
Resizables.removeObserver(this.container);
|
449 |
+
this.resizable.handle.stopObserving('mousedown',this.bringToFrontHandler);
|
450 |
+
this.resizable.destroy();
|
451 |
+
}
|
452 |
+
if(this.container && !this.sourceContainer)
|
453 |
+
this.container.remove();
|
454 |
+
if(this.sourceContainer){
|
455 |
+
if(this.options.hover){
|
456 |
+
this.sourceContainer.stopObserving('mouseenter',this.sourceContainerOpenHandler);
|
457 |
+
this.sourceContainer.stopObserving('mouseleave',this.sourceContainerCloseHandler);
|
458 |
+
if(this.options.position == 'mouse')
|
459 |
+
this.sourceContainer.stopObserving('mousemove',this.sourceContainerMouseMoveHandler);
|
460 |
+
}else
|
461 |
+
this.sourceContainer.stopObserving('click',this.sourceContainerOpenHandler);
|
462 |
+
}
|
463 |
+
if(this.iFrameShim)
|
464 |
+
this.iFrameShim.destroy();
|
465 |
+
Event.stopObserving(window,'resize',this.outOfBoundsPositionHandler);
|
466 |
+
Control.Window.windows = Control.Window.windows.without(this);
|
467 |
+
this.notify('afterDestroy');
|
468 |
+
},
|
469 |
+
//private
|
470 |
+
applyResizable: function(){
|
471 |
+
if(this.options.resizable){
|
472 |
+
if(typeof(Resizable) == "undefined")
|
473 |
+
throw "Control.Window requires resizable.js to be loaded.";
|
474 |
+
var resizable_handle = null;
|
475 |
+
if(this.options.resizable === true){
|
476 |
+
resizable_handle = new Element('div',{
|
477 |
+
className: 'resizable_handle'
|
478 |
+
});
|
479 |
+
this.container.insert(resizable_handle);
|
480 |
+
}else
|
481 |
+
resizable_handle = $(this.options.resziable);
|
482 |
+
this.resizable = new Resizable(this.container,{
|
483 |
+
handle: resizable_handle,
|
484 |
+
minHeight: this.options.minHeight,
|
485 |
+
minWidth: this.options.minWidth,
|
486 |
+
maxHeight: this.options.constrainToViewport ? function(element){
|
487 |
+
//viewport height - top - total border height
|
488 |
+
return (document.viewport.getDimensions().height - parseInt(element.style.top || 0)) - (element.getHeight() - parseInt(element.style.height || 0));
|
489 |
+
} : this.options.maxHeight,
|
490 |
+
maxWidth: this.options.constrainToViewport ? function(element){
|
491 |
+
//viewport width - left - total border width
|
492 |
+
return (document.viewport.getDimensions().width - parseInt(element.style.left || 0)) - (element.getWidth() - parseInt(element.style.width || 0));
|
493 |
+
} : this.options.maxWidth
|
494 |
+
});
|
495 |
+
this.resizable.handle.observe('mousedown',this.bringToFrontHandler);
|
496 |
+
Resizables.addObserver(new Control.Window.LayoutUpdateObserver(this,function(){
|
497 |
+
if(this.iFrameShim)
|
498 |
+
this.updateIFrameShimZIndex();
|
499 |
+
this.notify('onResize');
|
500 |
+
}.bind(this)));
|
501 |
+
}
|
502 |
+
},
|
503 |
+
applyDraggable: function(){
|
504 |
+
if(this.options.draggable){
|
505 |
+
if(typeof(Draggables) == "undefined")
|
506 |
+
throw "Control.Window requires dragdrop.js to be loaded.";
|
507 |
+
var draggable_handle = null;
|
508 |
+
if(this.options.draggable === true){
|
509 |
+
draggable_handle = new Element('div',{
|
510 |
+
className: 'draggable_handle'
|
511 |
+
});
|
512 |
+
this.container.insert(draggable_handle);
|
513 |
+
}else
|
514 |
+
draggable_handle = $(this.options.draggable);
|
515 |
+
this.draggable = new Draggable(this.container,{
|
516 |
+
handle: draggable_handle,
|
517 |
+
constrainToViewport: this.options.constrainToViewport,
|
518 |
+
zindex: this.container.getStyle('z-index'),
|
519 |
+
starteffect: function(){
|
520 |
+
if(Prototype.Browser.IE){
|
521 |
+
this.old_onselectstart = document.onselectstart;
|
522 |
+
document.onselectstart = function(){
|
523 |
+
return false;
|
524 |
+
};
|
525 |
+
}
|
526 |
+
}.bind(this),
|
527 |
+
endeffect: function(){
|
528 |
+
document.onselectstart = this.old_onselectstart;
|
529 |
+
}.bind(this)
|
530 |
+
});
|
531 |
+
this.draggable.handle.observe('mousedown',this.bringToFrontHandler);
|
532 |
+
Draggables.addObserver(new Control.Window.LayoutUpdateObserver(this,function(){
|
533 |
+
if(this.iFrameShim)
|
534 |
+
this.updateIFrameShimZIndex();
|
535 |
+
this.notify('onDrag');
|
536 |
+
}.bind(this)));
|
537 |
+
}
|
538 |
+
},
|
539 |
+
createDefaultContainer: function(container){
|
540 |
+
if(!this.container){
|
541 |
+
//no container passed or found, create it
|
542 |
+
this.container = new Element('div',{
|
543 |
+
id: 'control_window_' + this.numberInSequence
|
544 |
+
});
|
545 |
+
$(document.body).insert(this.container);
|
546 |
+
if(typeof(container) == "string" && $(container) == null && !container.match(/^#(.+)$/) && !container.match(Control.Window.uriRegex))
|
547 |
+
this.container.update(container);
|
548 |
+
}
|
549 |
+
},
|
550 |
+
finishOpen: function(event){
|
551 |
+
this.bringToFront();
|
552 |
+
if(this.options.fade){
|
553 |
+
if(typeof(Effect) == "undefined")
|
554 |
+
throw "Control.Window requires effects.js to be loaded."
|
555 |
+
if(this.effects.fade)
|
556 |
+
this.effects.fade.cancel();
|
557 |
+
this.effects.appear = new Effect.Appear(this.container,{
|
558 |
+
queue: {
|
559 |
+
position: 'end',
|
560 |
+
scope: 'Control.Window.' + this.numberInSequence
|
561 |
+
},
|
562 |
+
from: 0,
|
563 |
+
to: 1,
|
564 |
+
duration: this.options.fadeDuration / 2,
|
565 |
+
afterFinish: function(){
|
566 |
+
if(this.iFrameShim)
|
567 |
+
this.updateIFrameShimZIndex();
|
568 |
+
this.isOpen = true;
|
569 |
+
this.notify('afterOpen');
|
570 |
+
}.bind(this)
|
571 |
+
});
|
572 |
+
}else
|
573 |
+
this.container.show();
|
574 |
+
this.position(event);
|
575 |
+
if(!(this.options.draggable || this.options.resizable) && this.options.position == 'center')
|
576 |
+
Event.observe(window,'resize',this.positionHandler,false);
|
577 |
+
if(!this.options.draggable && this.options.position == 'center')
|
578 |
+
Event.observe(window,'scroll',this.positionHandler,false);
|
579 |
+
if(!this.options.fade){
|
580 |
+
this.isOpen = true;
|
581 |
+
this.notify('afterOpen');
|
582 |
+
}
|
583 |
+
return true;
|
584 |
+
},
|
585 |
+
showIndicator: function(){
|
586 |
+
this.showIndicatorTimeout = window.setTimeout(function(){
|
587 |
+
if(this.options.fade){
|
588 |
+
this.indicatorEffects.appear = new Effect.Appear(this.indicator,{
|
589 |
+
queue: {
|
590 |
+
position: 'front',
|
591 |
+
scope: 'Control.Window.indicator.' + this.numberInSequence
|
592 |
+
},
|
593 |
+
from: 0,
|
594 |
+
to: 1,
|
595 |
+
duration: this.options.fadeDuration / 2
|
596 |
+
});
|
597 |
+
}else
|
598 |
+
this.indicator.show();
|
599 |
+
}.bind(this),Control.Window.indicatorTimeout);
|
600 |
+
},
|
601 |
+
hideIndicator: function(){
|
602 |
+
if(this.showIndicatorTimeout)
|
603 |
+
window.clearTimeout(this.showIndicatorTimeout);
|
604 |
+
this.indicator.hide();
|
605 |
+
},
|
606 |
+
getRemoteContentInsertionTarget: function(){
|
607 |
+
return typeof(this.options.insertRemoteContentAt) == "string" ? this.container.down(this.options.insertRemoteContentAt) : $(this.options.insertRemoteContentAt);
|
608 |
+
},
|
609 |
+
updateIFrameShimZIndex: function(){
|
610 |
+
if(this.iFrameShim)
|
611 |
+
this.iFrameShim.positionUnder(this.container);
|
612 |
+
}
|
613 |
+
});
|
614 |
+
//class methods
|
615 |
+
Object.extend(Control.Window,{
|
616 |
+
windows: [],
|
617 |
+
baseZIndex: 9999,
|
618 |
+
indicatorTimeout: 250,
|
619 |
+
iframeTemplate: new Template('<iframe src="#{href}" width="100%" height="100%" frameborder="0"></iframe>'),
|
620 |
+
uriRegex: /^(\/|\#|https?\:\/\/|[\w]+\/)/,
|
621 |
+
bringToFront: function(w){
|
622 |
+
Control.Window.windows = Control.Window.windows.without(w);
|
623 |
+
Control.Window.windows.push(w);
|
624 |
+
Control.Window.windows.each(function(w,i){
|
625 |
+
var z_index = Control.Window.baseZIndex + i;
|
626 |
+
w.container.setStyle({
|
627 |
+
zIndex: z_index
|
628 |
+
});
|
629 |
+
if(w.isOpen){
|
630 |
+
if(w.iFrameShim)
|
631 |
+
w.updateIFrameShimZIndex();
|
632 |
+
}
|
633 |
+
if(w.options.draggable)
|
634 |
+
w.draggable.options.zindex = z_index;
|
635 |
+
});
|
636 |
+
},
|
637 |
+
open: function(container,options){
|
638 |
+
var w = new Control.Window(container,options);
|
639 |
+
w.open();
|
640 |
+
return w;
|
641 |
+
},
|
642 |
+
//protected
|
643 |
+
initialZIndexForWindow: function(w){
|
644 |
+
return Control.Window.baseZIndex + (Control.Window.windows.length - 1);
|
645 |
+
}
|
646 |
+
});
|
647 |
+
Object.Event.extend(Control.Window);
|
648 |
+
|
649 |
+
//this is the observer for both Resizables and Draggables
|
650 |
+
Control.Window.LayoutUpdateObserver = Class.create({
|
651 |
+
initialize: function(w,observer){
|
652 |
+
this.w = w;
|
653 |
+
this.element = $(w.container);
|
654 |
+
this.observer = observer;
|
655 |
+
},
|
656 |
+
onStart: Prototype.emptyFunction,
|
657 |
+
onEnd: function(event_name,instance){
|
658 |
+
if(instance.element == this.element && this.iFrameShim)
|
659 |
+
this.w.updateIFrameShimZIndex();
|
660 |
+
},
|
661 |
+
onResize: function(event_name,instance){
|
662 |
+
if(instance.element == this.element)
|
663 |
+
this.observer(this.element);
|
664 |
+
},
|
665 |
+
onDrag: function(event_name,instance){
|
666 |
+
if(instance.element == this.element)
|
667 |
+
this.observer(this.element);
|
668 |
+
}
|
669 |
+
});
|
670 |
+
|
671 |
+
//overlay for Control.Modal
|
672 |
+
Control.Overlay = {
|
673 |
+
id: 'control_overlay',
|
674 |
+
loaded: false,
|
675 |
+
container: false,
|
676 |
+
lastOpacity: 0,
|
677 |
+
getStyles: function() {
|
678 |
+
return {
|
679 |
+
position: 'fixed',
|
680 |
+
top: 0,
|
681 |
+
left: 0,
|
682 |
+
width: '100%',
|
683 |
+
height: '100%',
|
684 |
+
zIndex: Control.Window.baseZIndex - 1
|
685 |
+
};
|
686 |
+
},
|
687 |
+
getIeStyles: function() {
|
688 |
+
return {
|
689 |
+
position: 'absolute',
|
690 |
+
top: 0,
|
691 |
+
left: 0,
|
692 |
+
zIndex: Control.Window.baseZIndex - 1
|
693 |
+
};
|
694 |
+
},
|
695 |
+
effects: {
|
696 |
+
fade: false,
|
697 |
+
appear: false
|
698 |
+
},
|
699 |
+
load: function(){
|
700 |
+
if(Control.Overlay.loaded)
|
701 |
+
return false;
|
702 |
+
Control.Overlay.loaded = true;
|
703 |
+
Control.Overlay.container = new Element('div',{
|
704 |
+
id: Control.Overlay.id
|
705 |
+
});
|
706 |
+
$(document.body).insert(Control.Overlay.container);
|
707 |
+
if(Prototype.Browser.IE){
|
708 |
+
Control.Overlay.container.setStyle(Control.Overlay.getIeStyles());
|
709 |
+
Event.observe(window,'scroll',Control.Overlay.positionOverlay);
|
710 |
+
Event.observe(window,'resize',Control.Overlay.positionOverlay);
|
711 |
+
Control.Overlay.observe('beforeShow',Control.Overlay.positionOverlay);
|
712 |
+
}else
|
713 |
+
Control.Overlay.container.setStyle(Control.Overlay.getStyles());
|
714 |
+
Control.Overlay.iFrameShim = new IframeShim();
|
715 |
+
Control.Overlay.iFrameShim.hide();
|
716 |
+
Event.observe(window,'resize',Control.Overlay.positionIFrameShim);
|
717 |
+
Control.Overlay.container.hide();
|
718 |
+
return true;
|
719 |
+
},
|
720 |
+
unload: function(){
|
721 |
+
if(!Control.Overlay.loaded)
|
722 |
+
return false;
|
723 |
+
Event.stopObserving(window,'resize',Control.Overlay.positionOverlay);
|
724 |
+
Control.Overlay.stopObserving('beforeShow',Control.Overlay.positionOverlay);
|
725 |
+
Event.stopObserving(window,'resize',Control.Overlay.positionIFrameShim);
|
726 |
+
Control.Overlay.iFrameShim.destroy();
|
727 |
+
Control.Overlay.container.remove();
|
728 |
+
Control.Overlay.loaded = false;
|
729 |
+
return true;
|
730 |
+
},
|
731 |
+
show: function(opacity,fade){
|
732 |
+
if(Control.Overlay.notify('beforeShow') === false)
|
733 |
+
return false;
|
734 |
+
Control.Overlay.lastOpacity = opacity;
|
735 |
+
Control.Overlay.positionIFrameShim();
|
736 |
+
Control.Overlay.iFrameShim.show();
|
737 |
+
if(fade){
|
738 |
+
if(typeof(Effect) == "undefined")
|
739 |
+
throw "Control.Window requires effects.js to be loaded."
|
740 |
+
if(Control.Overlay.effects.fade)
|
741 |
+
Control.Overlay.effects.fade.cancel();
|
742 |
+
Control.Overlay.effects.appear = new Effect.Appear(Control.Overlay.container,{
|
743 |
+
queue: {
|
744 |
+
position: 'end',
|
745 |
+
scope: 'Control.Overlay'
|
746 |
+
},
|
747 |
+
afterFinish: function(){
|
748 |
+
Control.Overlay.notify('afterShow');
|
749 |
+
},
|
750 |
+
from: 0,
|
751 |
+
to: Control.Overlay.lastOpacity,
|
752 |
+
duration: (fade === true ? 0.75 : fade) / 2
|
753 |
+
});
|
754 |
+
}else{
|
755 |
+
Control.Overlay.container.setStyle({
|
756 |
+
opacity: opacity || 1
|
757 |
+
});
|
758 |
+
Control.Overlay.container.show();
|
759 |
+
Control.Overlay.notify('afterShow');
|
760 |
+
}
|
761 |
+
return true;
|
762 |
+
},
|
763 |
+
hide: function(fade){
|
764 |
+
if(Control.Overlay.notify('beforeHide') === false)
|
765 |
+
return false;
|
766 |
+
if(Control.Overlay.effects.appear)
|
767 |
+
Control.Overlay.effects.appear.cancel();
|
768 |
+
Control.Overlay.iFrameShim.hide();
|
769 |
+
if(fade){
|
770 |
+
Control.Overlay.effects.fade = new Effect.Fade(Control.Overlay.container,{
|
771 |
+
queue: {
|
772 |
+
position: 'front',
|
773 |
+
scope: 'Control.Overlay'
|
774 |
+
},
|
775 |
+
afterFinish: function(){
|
776 |
+
Control.Overlay.notify('afterHide');
|
777 |
+
},
|
778 |
+
from: Control.Overlay.lastOpacity,
|
779 |
+
to: 0,
|
780 |
+
duration: (fade === true ? 0.75 : fade) / 2
|
781 |
+
});
|
782 |
+
}else{
|
783 |
+
Control.Overlay.container.hide();
|
784 |
+
Control.Overlay.notify('afterHide');
|
785 |
+
}
|
786 |
+
return true;
|
787 |
+
},
|
788 |
+
positionIFrameShim: function(){
|
789 |
+
if(Control.Overlay.container.visible())
|
790 |
+
Control.Overlay.iFrameShim.positionUnder(Control.Overlay.container);
|
791 |
+
},
|
792 |
+
//IE only
|
793 |
+
positionOverlay: function(){
|
794 |
+
Control.Overlay.container.setStyle({
|
795 |
+
width: document.body.clientWidth + 'px',
|
796 |
+
height: document.body.clientHeight + 'px'
|
797 |
+
});
|
798 |
+
}
|
799 |
+
};
|
800 |
+
Object.Event.extend(Control.Overlay);
|
801 |
+
|
802 |
+
Control.ToolTip = Class.create(Control.Window,{
|
803 |
+
initialize: function($super,container,tooltip,options){
|
804 |
+
$super(tooltip,Object.extend(Object.extend(Object.clone(Control.ToolTip.defaultOptions),options || {}),{
|
805 |
+
position: 'mouse',
|
806 |
+
hover: container
|
807 |
+
}));
|
808 |
+
}
|
809 |
+
});
|
810 |
+
Object.extend(Control.ToolTip,{
|
811 |
+
defaultOptions: {
|
812 |
+
offsetLeft: 10
|
813 |
+
}
|
814 |
+
});
|
815 |
+
|
816 |
+
Control.Modal = Class.create(Control.Window,{
|
817 |
+
initialize: function($super,container,options){
|
818 |
+
Control.Modal.InstanceMethods.beforeInitialize.bind(this)();
|
819 |
+
$super(container,Object.extend(Object.clone(Control.Modal.defaultOptions),options || {}));
|
820 |
+
},
|
821 |
+
closeWithoutOverlay: function(){
|
822 |
+
this.keepOverlay = true;
|
823 |
+
this.close();
|
824 |
+
}
|
825 |
+
});
|
826 |
+
Object.extend(Control.Modal,{
|
827 |
+
defaultOptions: {
|
828 |
+
overlayOpacity: 0.5,
|
829 |
+
closeOnClick: 'overlay'
|
830 |
+
},
|
831 |
+
current: false,
|
832 |
+
open: function(container,options){
|
833 |
+
var modal = new Control.Modal(container,options);
|
834 |
+
modal.open();
|
835 |
+
return modal;
|
836 |
+
},
|
837 |
+
close: function(){
|
838 |
+
if(Control.Modal.current)
|
839 |
+
Control.Modal.current.close();
|
840 |
+
},
|
841 |
+
InstanceMethods: {
|
842 |
+
beforeInitialize: function(){
|
843 |
+
Control.Overlay.load();
|
844 |
+
this.observe('beforeOpen',Control.Modal.Observers.beforeOpen.bind(this));
|
845 |
+
this.observe('afterOpen',Control.Modal.Observers.afterOpen.bind(this));
|
846 |
+
this.observe('afterClose',Control.Modal.Observers.afterClose.bind(this));
|
847 |
+
}
|
848 |
+
},
|
849 |
+
Observers: {
|
850 |
+
beforeOpen: function(){
|
851 |
+
Control.Window.windows.without(this).each(function(w){
|
852 |
+
if(w.closeWithoutOverlay && w.isOpen){
|
853 |
+
w.closeWithoutOverlay();
|
854 |
+
}else{
|
855 |
+
w.close();
|
856 |
+
}
|
857 |
+
});
|
858 |
+
if(!Control.Overlay.overlayFinishedOpening){
|
859 |
+
Control.Overlay.observeOnce('afterShow',function(){
|
860 |
+
Control.Overlay.overlayFinishedOpening = true;
|
861 |
+
this.open();
|
862 |
+
}.bind(this));
|
863 |
+
Control.Overlay.show(this.options.overlayOpacity,this.options.fade ? this.options.fadeDuration : false);
|
864 |
+
throw $break;
|
865 |
+
}
|
866 |
+
},
|
867 |
+
afterOpen: function(){
|
868 |
+
Control.Overlay.show(this.options.overlayOpacity);
|
869 |
+
Control.Overlay.overlayFinishedOpening = true;
|
870 |
+
Control.Modal.current = this;
|
871 |
+
},
|
872 |
+
afterClose: function(){
|
873 |
+
if(!this.keepOverlay){
|
874 |
+
Control.Overlay.hide(this.options.fade ? this.options.fadeDuration : false);
|
875 |
+
Control.Overlay.overlayFinishedOpening = false;
|
876 |
+
}
|
877 |
+
this.keepOverlay = false;
|
878 |
+
Control.Modal.current = false;
|
879 |
+
}
|
880 |
+
}
|
881 |
+
});
|
882 |
+
|
883 |
+
Control.LightBox = Class.create(Control.Window,{
|
884 |
+
initialize: function($super,container,options){
|
885 |
+
this.allImagesLoaded = false;
|
886 |
+
if(options.modal){
|
887 |
+
var options = Object.extend(Object.clone(Control.LightBox.defaultOptions),options || {});
|
888 |
+
options = Object.extend(Object.clone(Control.Modal.defaultOptions),options);
|
889 |
+
options = Control.Modal.InstanceMethods.beforeInitialize.bind(this)(options);
|
890 |
+
$super(container,options);
|
891 |
+
}else
|
892 |
+
$super(container,Object.extend(Object.clone(Control.LightBox.defaultOptions),options || {}));
|
893 |
+
this.hasRemoteContent = this.href && !this.options.iframe;
|
894 |
+
if(this.hasRemoteContent)
|
895 |
+
this.observe('onRemoteContentLoaded',Control.LightBox.Observers.onRemoteContentLoaded.bind(this));
|
896 |
+
else
|
897 |
+
this.applyImageObservers();
|
898 |
+
this.observe('beforeOpen',Control.LightBox.Observers.beforeOpen.bind(this));
|
899 |
+
},
|
900 |
+
applyImageObservers:function(){
|
901 |
+
var images = this.getImages();
|
902 |
+
this.numberImagesToLoad = images.length;
|
903 |
+
this.numberofImagesLoaded = 0;
|
904 |
+
images.each(function(image){
|
905 |
+
image.observe('load',function(image){
|
906 |
+
++this.numberofImagesLoaded;
|
907 |
+
if(this.numberImagesToLoad == this.numberofImagesLoaded){
|
908 |
+
this.allImagesLoaded = true;
|
909 |
+
this.onAllImagesLoaded();
|
910 |
+
}
|
911 |
+
}.bind(this,image));
|
912 |
+
image.hide();
|
913 |
+
}.bind(this));
|
914 |
+
},
|
915 |
+
onAllImagesLoaded: function(){
|
916 |
+
this.getImages().each(function(image){
|
917 |
+
this.showImage(image);
|
918 |
+
}.bind(this));
|
919 |
+
if(this.hasRemoteContent){
|
920 |
+
if(this.options.indicator)
|
921 |
+
this.hideIndicator();
|
922 |
+
this.finishOpen();
|
923 |
+
}else
|
924 |
+
this.open();
|
925 |
+
},
|
926 |
+
getImages: function(){
|
927 |
+
return this.container.select(Control.LightBox.imageSelector);
|
928 |
+
},
|
929 |
+
showImage: function(image){
|
930 |
+
image.show();
|
931 |
+
}
|
932 |
+
});
|
933 |
+
Object.extend(Control.LightBox,{
|
934 |
+
imageSelector: 'img',
|
935 |
+
defaultOptions: {},
|
936 |
+
Observers: {
|
937 |
+
beforeOpen: function(){
|
938 |
+
if(!this.hasRemoteContent && !this.allImagesLoaded)
|
939 |
+
throw $break;
|
940 |
+
},
|
941 |
+
onRemoteContentLoaded: function(){
|
942 |
+
this.applyImageObservers();
|
943 |
+
if(!this.allImagesLoaded)
|
944 |
+
throw $break;
|
945 |
+
}
|
946 |
+
}
|
947 |
+
});
|
package.xml
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>Eabi_Livehandler</name>
|
4 |
+
<version>0.1.1</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL 3.0</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary><p>View detailed order information and navigate with up-down arrows in Order Grid</p></summary>
|
10 |
+
<description><p>When in the Order Grid view, extra button is added next to Bill-to name</p>
|
11 |
+
<p>Clicking on the <strong>Show order</strong> button opens up detailed order view in a modal box</p>
|
12 |
+
<p>You can navigate between orders by pressing directional keys or by pressing left/right icons on the order view</p>
|
13 |
+
<p>Possibility to create your own action buttons, which allows to save lots of time when managing orders</p>
|
14 |
+
<p>Possibility to purchase action buttons like <strong>Add order comment</strong>, <strong>Create invoice</strong>, <strong>Ship order</strong> and more</p></description>
|
15 |
+
<notes>Initial release</notes>
|
16 |
+
<authors><author><name>Matis Matis</name><user>auto-converted</user><email>info@e-abi.ee</email></author></authors>
|
17 |
+
<date>2013-05-10</date>
|
18 |
+
<time>11:49:50</time>
|
19 |
+
<contents><target name="magecommunity"><dir name="Eabi"><dir name="Livehandler"><dir name="Block"><dir name="Adminhtml"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Button.php" hash="33d3eb40f2c23ba4661956015336b8a4"/><file name="Remove.php" hash="54d09373da925081e36e90f0713660f2"/></dir></dir></dir></dir><file name="Footer.php" hash="23def3333fb7b464ef413d13d47b22bc"/></dir><dir name="Helper"><file name="Data.php" hash="210262e1f1929c97f03aa8ee87f30543"/></dir><dir name="Model"><dir name="Action"><file name="Abstract.php" hash="2cf8b22eca0a121c5ecd2bcd983e222d"/></dir><dir name="Adminhtml"><file name="Gridmanager.php" hash="c1af0869fe074a2c496545373e959907"/></dir><dir name="Mysql4"><dir name="Entry"><file name="Collection.php" hash="dc56ff6d43a19bf558366c0ac083ee25"/></dir><file name="Entry.php" hash="60f7ed0c56032c4edfa7f692d9d3c5f4"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Button.php" hash="f6a5cf74036476d415e099c5cf7002ec"/></dir></dir></dir><file name="Abstract.php" hash="6cdd59c0287e6b4b37a34da627115c0f"/><file name="Entry.php" hash="cfda34f7cff6c58cee650722c04a0224"/><file name="Ordergrid.php" hash="b6df6c941135fba22d82e963349fa173"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="LivehandlerController.php" hash="6e106b3c9fa0117de3716ff3c9b47433"/><file name="RemoveController.php" hash="0901ae14e66230dabc3efb74065ff751"/></dir><file name="IndexController.php" hash="ab82c51048d2f5d36494252881809d52"/></dir><dir name="etc"><file name="config.xml" hash="092cd67dfa9fb3504f86d2b0124017f4"/><file name="system.xml" hash="937c6262391f79a5e21b0c6c32d6a3dd"/></dir><dir name="sql"><dir name="eabi_livehandler_setup"><file name="mysql4-install-0.1.0.php" hash="8f16385a82b16684ed7dc9e790a57ecf"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="d1fa18164c000376233ba200d42e729f"/></dir></dir><file name="CHANGELOG.txt" hash="c1462eeb9d109135e8d451c7341c4e3b"/><file name="LICENCE.txt" hash="0191312e121c0b3e1165619b96efcf9f"/></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="eabi_livehandler.xml" hash="662184a16683705946f3df92fea51a15"/></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="eabi_livehandler.xml" hash="205818bff253ab57a259c31c7cd29352"/></dir></dir></dir><dir name="base"><dir name="default"><dir name="layout"><file name="eabi_livehandler.xml" hash="205818bff253ab57a259c31c7cd29352"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Eabi_Livehandler.xml" hash="2579407bdedb1ea05cb5d516052d5503"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Eabi_Livehandler.csv" hash="6e070637c1109df358ca7913a5a67458"/></dir><dir name="et_EE"><file name="Eabi_Livehandler.csv" hash="a30b4f480458b711e6a398e6fc153359"/></dir><dir name="fi_FI"><file name="Eabi_Livehandler.csv" hash="6e070637c1109df358ca7913a5a67458"/></dir><dir name="lt_LT"><file name="Eabi_Livehandler.csv" hash="6e070637c1109df358ca7913a5a67458"/></dir><dir name="sv_SE"><file name="Eabi_Livehandler.csv" hash="6e070637c1109df358ca7913a5a67458"/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><file name="eabi_admintools.css" hash="fa4d08faa9c1300e9a543ff408557c38"/></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="eabi_js"><file name="crossBrowser_initKeyboardEvent.js" hash="8600c5536225fd70c56ef313ee430e08"/></dir><dir name="livepipe"><file name="contextmenu.js" hash="a5dbab9663d94d9d848e84b524c1f925"/><file name="cookie.js" hash="eab2042ac637aec7777c7c64e3e2bb1a"/><file name="event_behavior.js" hash="a59a00ad652efb1596b5bd2e6f5cfe48"/><file name="hotkey.js" hash="c6193fc03e4cd4c94ee4fb37e3d5ed6b"/><file name="livepipe.js" hash="6e569402b2686976e7390f0b7a25b1eb"/><file name="progressbar.js" hash="69719eccbecbc0378d9919c53a3ef7dd"/><file name="rating.js" hash="adb5ce773c37b40fb590a877d949be7a"/><file name="resizable.js" hash="38fd18daa37e5612495cc7b42fd32b3d"/><file name="scrollbar.js" hash="7a2603c2107944b8a70e41e7a84133ba"/><file name="selection.js" hash="3f48981cccffdb5fcc5f5ff27d0b0b68"/><file name="selectmultiple.js" hash="d8f044eb344061bdcce405f671b15654"/><file name="tabs.js" hash="22abb9a3ec3933d54ff9ede0338ca7f3"/><file name="textarea.js" hash="9825782bf78d38efa53200a206d8cd77"/><file name="window.js" hash="f6eba488d6a80e05f59d97a0cef59730"/></dir></dir></target></contents>
|
20 |
+
<compatible/>
|
21 |
+
<dependencies/>
|
22 |
+
</package>
|
skin/adminhtml/default/default/eabi_admintools.css
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
Document : eabi_admintools.css
|
3 |
+
Created on : 2.05.2012, 12:58:01
|
4 |
+
Author : matishalmann
|
5 |
+
Description:
|
6 |
+
Purpose of the stylesheet follows.
|
7 |
+
*/
|
8 |
+
|
9 |
+
#control_overlay {
|
10 |
+
background:none repeat scroll 0 0 #000000;
|
11 |
+
opacity: 0.5;
|
12 |
+
filter: alpha(opacity=50);
|
13 |
+
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
|
14 |
+
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
|
15 |
+
}
|
16 |
+
|
17 |
+
.modal {
|
18 |
+
background-color:#fff;
|
19 |
+
padding:10px;
|
20 |
+
border:1px solid #333;
|
21 |
+
}
|
22 |
+
|
23 |
+
.tooltip {
|
24 |
+
border:1px solid #000;
|
25 |
+
background-color:#fff;
|
26 |
+
height:25px;
|
27 |
+
width:200px;
|
28 |
+
font-family:"Lucida Grande",Verdana;
|
29 |
+
font-size:10px;
|
30 |
+
color:#333;
|
31 |
+
}
|
32 |
+
|
33 |
+
.simple_window {
|
34 |
+
width:250px;
|
35 |
+
height:50px;
|
36 |
+
border:1px solid #000;
|
37 |
+
background-color:#fff;
|
38 |
+
padding:10px;
|
39 |
+
text-align:left;
|
40 |
+
font-family:"Lucida Grande",Verdana;
|
41 |
+
font-size:12px;
|
42 |
+
color:#333;
|
43 |
+
}
|
44 |
+
|
45 |
+
.eabi_window {
|
46 |
+
background-image:url("images/bg_window_mask.png");
|
47 |
+
background-position:top left;
|
48 |
+
-moz-border-radius: 10px;
|
49 |
+
-webkit-border-radius: 10px;
|
50 |
+
border-radius: 10px;
|
51 |
+
padding:10px;
|
52 |
+
font-family:"Lucida Grande",Verdana;
|
53 |
+
font-size:13px;
|
54 |
+
color:#000;
|
55 |
+
text-align:center;
|
56 |
+
min-width:550px;
|
57 |
+
min-height:229px;
|
58 |
+
width: 768px;
|
59 |
+
}
|
60 |
+
|
61 |
+
|
62 |
+
.eabi_window .button_box {
|
63 |
+
border: 1px solid #000;
|
64 |
+
background: #fff;
|
65 |
+
height: 100px;
|
66 |
+
width: 300px;
|
67 |
+
padding: 5px;
|
68 |
+
|
69 |
+
}
|
70 |
+
|
71 |
+
.eabi_window_bg {
|
72 |
+
background-image:url("images/box_bg.gif");
|
73 |
+
}
|
74 |
+
|
75 |
+
.eabi_window .window_contents {
|
76 |
+
margin-top:10px;
|
77 |
+
width:100%;
|
78 |
+
height:100%;
|
79 |
+
}
|
80 |
+
|
81 |
+
.eabi_window .window_contents a {
|
82 |
+
display: inline !important;
|
83 |
+
}
|
84 |
+
.eabi_window .eabi_arrow {
|
85 |
+
height: 13px;
|
86 |
+
width: 13px;
|
87 |
+
cursor: pointer;
|
88 |
+
display: inline-block;
|
89 |
+
position: absolute;
|
90 |
+
top: 100px;
|
91 |
+
}
|
92 |
+
.eabi_window #eabi_previous {
|
93 |
+
float: left;
|
94 |
+
left: 0px;
|
95 |
+
background: url("images/pager_arrow_left.gif") no-repeat;
|
96 |
+
}
|
97 |
+
.eabi_window #eabi_next {
|
98 |
+
float: right;
|
99 |
+
right: 0px;
|
100 |
+
background: url("images/pager_arrow_right.gif") no-repeat;
|
101 |
+
}
|
102 |
+
|
103 |
+
.eabi_window .window_header {
|
104 |
+
text-align:center;
|
105 |
+
}
|
106 |
+
|
107 |
+
.eabi_window .window_title {
|
108 |
+
margin-top:-7px;
|
109 |
+
margin-bottom:7px;
|
110 |
+
font-size:13px;
|
111 |
+
font-weight: bold;
|
112 |
+
}
|
113 |
+
|
114 |
+
.eabi_window .window_close {
|
115 |
+
display:block;
|
116 |
+
position:absolute;
|
117 |
+
top:4px;
|
118 |
+
right:5px;
|
119 |
+
height:16px;
|
120 |
+
width:16px;
|
121 |
+
background-image: url("images/window_close.png");
|
122 |
+
cursor:pointer;
|
123 |
+
background-repeat: no-repeat;
|
124 |
+
}
|
125 |
+
|
126 |
+
.eabi_window .window_contents .products_grid tr {
|
127 |
+
width: 764px;
|
128 |
+
}
|
129 |
+
.eabi_window .window_contents .products_grid {
|
130 |
+
width: 768px;
|
131 |
+
}
|
132 |
+
.eabi_window .window_contents .products_grid th {
|
133 |
+
max-width: 190px;
|
134 |
+
}
|
135 |
+
.eabi_window .window_contents .products_grid td {
|
136 |
+
max-width: 190px;
|
137 |
+
}
|
138 |
+
|
139 |
+
.eabi_window_bg .window_close {
|
140 |
+
background-image:url("images/icon_btn_delete.gif");
|
141 |
+
}
|
142 |
+
|
143 |
+
.eabi_window .eabi_orderview_actionbutton {
|
144 |
+
float: left;
|
145 |
+
}
|
146 |
+
|
147 |
+
.eabi_window .eabi_buttons {
|
148 |
+
max-width: 455px;
|
149 |
+
display: table;
|
150 |
+
float: left;
|
151 |
+
}
|
152 |
+
|
153 |
+
.eabi_window .eabi_commercial {
|
154 |
+
color: #2d444f;
|
155 |
+
}
|
156 |
+
.eabi_window .eabi_commercial a {
|
157 |
+
text-decoration: none;
|
158 |
+
color: #ea7601 !important;
|
159 |
+
}
|
160 |
+
.eabi_window .eabi_commercial a:hover {
|
161 |
+
text-decoration: underline !important;
|
162 |
+
}
|
163 |
+
|
164 |
+
.eabi_window .order-totals table td {
|
165 |
+
padding: 0 !important;
|
166 |
+
}
|
167 |
+
.eabi_window .order-totals table td.label {
|
168 |
+
padding-right: 10px !important;
|
169 |
+
}
|