'ipblock' => true,
);
global $manager;
- $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
+ //$manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
$spam = false;
if (isset($spamcheck['result']) && $spamcheck['result'] == true){
$spam = true;
);
if ($member->isLoggedIn() && $member->isAdmin()){
- $adminurl = $manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=list&id=' . intval($tb_id));
- $pingformurl = $manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id));
+ $adminurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=list&id=' . intval($tb_id)), ENT_QUOTES);
+ $pingformurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id)), ENT_QUOTES);
$gVars['admin'] = '<a href="' . $adminurl . '" target="_blank">[admin]</a>';
$gVars['pingform'] = '<a href="' . $pingformurl . '" target="_blank">[pingform]</a>';
}
$desc = $this->_cut_string($desc, 200);
$desc = htmlspecialchars($desc, ENT_QUOTES);
- $timestamp = time();
- $sourceaddr = ip2long(serverVar('REMOTE_ADDR'));
- $key = md5( sprintf("%u %u %u %s", $timestamp, $sourceaddr, $itemid, __FILE__));
?>
<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
}
//mod by cles
// check: accept pings.
- if( $this->getBlogOption(getBlogIDFromItemID($tb_id), "AllowTrackBack") == 'yes' )
+ $blogId = getBlogIDFromItemID($tb_id);
+
+ if( $this->getBlogOption($blogId, "AllowTrackBack") == 'yes' )
$isAcceptPing = ( $this->getItemOption($tb_id, 'ItemAcceptPing') == 'yes' ) ? true : false ;
else
$isAcceptPing = false;
// 1. Get attributes
//modify start+++++++++
- $b =& $manager->getBlog(getBlogIDFromItemID($tb_id));
+ $b =& $manager->getBlog($blogId);
//modify end+++++++++
$url = requestVar('url');
$title = requestVar('title');
}
// 7. Send notification e-mail if needed
- if ($this->getOption('Notify') == 'yes' && $spam == false)
+ $notifyAddrs = $this->getOption('NotifyEmail');
+ $notifyAddrs = ( $notifyAddrs ? $notifyAddrs . ';' : '')
+ . $this->getBlogOption($blogId ,'NotifyEmailBlog');
+
+ if ($notifyAddrs && $spam == false)
{
- $destAddress = $this->getOption('NotifyEmail');
-
$vars = array (
'tb_id' => $tb_id,
if (!class_exists('notification'))
include($DIR_LIBS . 'NOTIFICATION.php');
- $notify = new NOTIFICATION($destAddress);
+ $notify = new NOTIFICATION($notifyAddrs);
$notify->notify($mailto_title, $mailto_msg , $CONF['AdminEmail']);
+
//mod by cles+++++++++++
if ($manager->pluginInstalled('NP_Cache')){
$p =& $manager->getPlugin('NP_Cache');
}
//mod by cles end +++++++++++
}
+
+ if( $block )
+ return 'Sorry, trackback ping is not accepted.';
return '';
}
{
$links = array();
- if (preg_match_all('/<a ([^>]+)>/', $text, $array, PREG_SET_ORDER))
+ if (preg_match_all('/<[aA] +([^>]+)>/', $text, $array, PREG_SET_ORDER))
{
for ($i = 0; $i < count($array); $i++)
{
- preg_match('/href="http:\/\/(.+?)"/', $array[$i][1], $matches);
- $links['http://'.$matches[1]] = 1;
+ //if( preg_match('/s?https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+/', $array[$i][1], $matches) )
+ if( preg_match('/s?https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/:@&=+$,%]+/', $array[$i][1], $matches) )
+ $links[$matches[0]] = 1;
}
}
function getName() { return 'TrackBack'; }
function getAuthor() { return 'rakaz + nakahara21 + hsur'; }
function getURL() { return 'http://blog.cles.jp/np_cles/category/31/subcatid/3'; }
- function getVersion() { return '2.0.3 jp7'; }
+ function getVersion() { return '2.0.3 jp8'; }
function getDescription() { return _TB_DESCRIPTION; }
//modify start+++++++++
$this->createOption('tplTbMore', _TB_tplTbMore, 'text', "<%number%> Trackbacks");
$this->createOption('dateFormat', _TB_dateFormat, 'text', _TB_dateFormat_VAL);
- $this->createOption('Notify', _TB_Notify,'yesno','no');
- $this->createOption('NotifyEmail', _TB_NotifyEmail,'text','');
-
+ $this->createOption('NotifyEmail', _TB_NotifyEmail,'text','');
$this->createOption('DropTable', _TB_DropTable,'yesno','no');
//mod by cles
$this->createOption('HideUrl',_TB_HideUrl,'yesno','yes');
+ $this->createOption('ajaxEnabled',_TB_ajaxEnabled,'yesno','no');
+
$this->createItemOption('ItemAcceptPing',_TB_ItemAcceptPing,'yesno','yes');
$this->createItemOption('isAcceptW/OLink',_TB_isAcceptWOLink,'select','default', _TB_isAcceptWOLink_VAL);
+ $this->createBlogOption('NotifyEmailBlog', _TB_NotifyEmailBlog,'text','');
$this->createBlogOption('isAcceptW/OLinkDef',_TB_isAcceptWOLinkDef,'select','block', _TB_isAcceptWOLinkDef_VAL);
$this->createBlogOption('AllowTrackBack',_TB_AllowTrackBack,'yesno','yes');
//mod by cles end
$this->notificationMailTitle = _TB_NORTIFICATION_MAIL_TITLE;
}
}
-
-?>
--- /dev/null
+<?php
+
+ $strRel = '../../../';
+ include($strRel . 'config.php');
+ include($DIR_LIBS . 'PLUGINADMIN.php');
+ include('template.php');
+
+ // Send out Content-type
+ header('Pragma: no-cache');
+ header("Content-Type: text/xml");
+ sendContentType('text/xml', 'admin-trackback', _CHARSET);
+
+ $oPluginAdmin = new PluginAdmin('TrackBack');
+
+ if (!($member->isLoggedIn() && $member->isAdmin()))
+ {
+ $oPluginAdmin->start();
+ echo '<p>' . _ERROR_DISALLOWED . '</p>';
+ $oPluginAdmin->end();
+ exit;
+ }
+
+ // Actions
+ $action = requestVar('action');
+ $aActionsNotToCheck = array(
+ '',
+ );
+ if (!in_array($action, $aActionsNotToCheck)) {
+ if (!$manager->checkTicket()) doError(_ERROR_BADTICKET);
+ }
+
+//modify start+++++++++
+ $plug =& $oPluginAdmin->plugin;
+ $tableVersion = $plug->checkTableVersion();
+
+ // include language file for this plugin
+ $language = ereg_replace( '[\\|/]', '', getLanguageName());
+ if (file_exists($plug->getDirectory().'language/'.$language.'.php'))
+ include_once($plug->getDirectory().'language/'.$language.'.php');
+ else
+ include_once($plug->getDirectory().'language/'.'english.php');
+//modify end+++++++++
+
+ $oTemplate = new Trackback_Template();
+ $oTemplate->set ('CONF', $CONF);
+ $oTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL());
+ $oTemplate->set ('ticket', $manager->_generateTicket());
+
+ // Pages
+ switch($action) {
+
+ case 'ajax':
+ $type = requestVar('type') == 'all' ? 'all' : 'blocked' ;
+ $filter['all'] = 't.block = 0';
+ $filter['blocked'] = 't.block = 1';
+
+ $start = intRequestVar('offset') ? intRequestVar('offset') : 0;
+ $amount = intRequestVar('page_size') ? intRequestVar('page_size') : 25;
+
+ $colname = array();
+ $colname['date'] = 'timestamp';
+ $colname['item'] = 'story_id';
+ $colname['title'] = 'title';
+
+ $sort_col = requestVar('sort_col');
+ $sort_col = $colname[$sort_col];
+ if( !$sort_col ) $sort_col = $colname['date'];
+
+ $sort_dir = ( requestVar('sort_dir') == 'ASC' ) ? 'ASC' : 'DESC';
+
+ $rres = mysql_query ("
+ SELECT
+ i.ititle AS story,
+ i.inumber AS story_id,
+ t.id AS id,
+ t.title AS title,
+ t.blog_name AS blog_name,
+ t.excerpt AS excerpt,
+ t.url AS url,
+ t.spam AS spam,
+ UNIX_TIMESTAMP(t.timestamp) AS timestamp
+ FROM
+ ".sql_table('plugin_tb')." AS t,
+ ".sql_table('item')." AS i
+ WHERE
+ t.tb_id = i.inumber AND
+ ".$filter[$type]."
+ ORDER BY
+ ".$sort_col." ".$sort_dir."
+ LIMIT
+ ".$start.",".$amount."
+ ");
+
+ $items = array();
+
+ while ($rrow = mysql_fetch_array($rres))
+ {
+ $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50);
+ $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']);
+ $rrow['title'] = htmlspecialchars($rrow['title']);
+ // $rrow['title'] = _CHARSET == 'UTF-8' ? $rrow['title'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['title']);
+
+ $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50);
+ $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']);
+ $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']);
+ // $rrow['blog_name'] = _CHARSET == 'UTF-8' ? $rrow['blog_name'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['blog_name']);
+
+ $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 100);
+ $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']);
+ $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']);
+ // $rrow['excerpt'] = _CHARSET == 'UTF-8' ? $rrow['excerpt'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['excerpt']);
+
+ $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES);
+
+ $blog = & $manager->getBlog(getBlogIDFromItemID($rrow['story_id']));
+ $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog);
+ $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES);
+
+ $items[] = $rrow;
+ }
+
+ $oTemplate->set ('amount', $amount);
+ $oTemplate->set ('count', $count);
+ $oTemplate->set ('start', $start);
+ $oTemplate->set ('items', $items);
+ $oTemplate->template('templates/response_'.$type.'.xml');
+ break;
+ }
+
+ // Create the admin area page
+ echo $oTemplate->fetch();
+
// Send out Content-type
sendContentType('application/xhtml+xml', 'admin-trackback', _CHARSET);
- // Compatiblity with Nucleus < = 2.0
- if (!function_exists('sql_table')) { function sql_table($name) { return 'nucleus_' . $name; } }
-
-
-
$oPluginAdmin = new PluginAdmin('TrackBack');
if (!($member->isLoggedIn() && $member->isAdmin()))
$mTemplate = new Trackback_Template();
$mTemplate->set ('CONF', $CONF);
- $mTemplate->set ('plugid', $plug->getID());\r $mTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL());
+ $mTemplate->set ('plugid', $plug->getID());
+ $mTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL());
$mTemplate->template('templates/menu.html');
echo $mTemplate->fetch();
$oTemplate = new Trackback_Template();
$oTemplate->set ('CONF', $CONF);
$oTemplate->set ('plugindirurl', $oPluginAdmin->plugin->getAdminURL());
+ $oTemplate->set ('ticket', $manager->_generateTicket());
+ \r $ajaxEnabled = ($oPluginAdmin->plugin->getOption('ajaxEnabled') == 'yes') ? true : false;
+ $oTemplate->set ('ajaxEnabled', $ajaxEnabled);
switch($action) {
break;
case 'blocked':
- $start = intRequestVar('start') ? intRequestVar('start') : 0;
- $amount = intRequestVar('amount') ? intRequestVar('amount') : 25;
-
+ case 'all':
$rres = mysql_query ("
SELECT
COUNT(*) AS count
".sql_table('item')." AS i
WHERE
t.tb_id = i.inumber AND
- t.block = 1
- ");
+ t.block = " . (( $action == 'all') ? 0 : 1) );
if ($row = mysql_fetch_array($rres))
$count = $row['count'];
else
$count = 0;
-
- $rres = mysql_query ("
- SELECT
+ $oTemplate->set('count', $count);
+
+ if($ajaxEnabled){
+ if( $action == 'all')
+ $oTemplate->template('templates/all_ajax.html');
+ else
+ $oTemplate->template('templates/blocked_ajax.html');
+ } else {\r $start = intRequestVar('start') ? intRequestVar('start') : 0;
+ $amount = intRequestVar('amount') ? intRequestVar('amount') : 25;
+
+ $rres = mysql_query ("
+ SELECT
i.ititle AS story,
i.inumber AS story_id,
t.id AS id,
t.blog_name AS blog_name,
t.excerpt AS excerpt,
t.url AS url,
- -- UNIX_TIMESTAMP(t.timestamp) AS timestamp,
t.timestamp AS timestamp,
t.spam AS spam,
t.link AS link
- FROM
+ FROM
".sql_table('plugin_tb')." AS t,
".sql_table('item')." AS i
- WHERE
+ WHERE
t.tb_id = i.inumber AND
- t.block = 1
- ORDER BY
+ t.block = " . (( $action == 'all') ? 0 : 1) ."
+ ORDER BY
timestamp DESC
- LIMIT
- ".$start.",".$amount."
- ");
-
- $items = array();
-
- while ($rrow = mysql_fetch_array($rres))
- {
- $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50);
- $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']);
- $rrow['title'] = htmlspecialchars($rrow['title']);
-// $rrow['title'] = _CHARSET == 'UTF-8' ? $rrow['title'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['title']);
-
- $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50);
- $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']);
- $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']);
-// $rrow['blog_name'] = _CHARSET == 'UTF-8' ? $rrow['blog_name'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['blog_name']);
-
- $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800);
- $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']);
- $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']);
-// $rrow['excerpt'] = _CHARSET == 'UTF-8' ? $rrow['excerpt'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['excerpt']);
-
- $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES);
- $rrow['timestamp'] = htmlspecialchars($rrow['timestamp'], ENT_QUOTES);
+ LIMIT
+ ".$start.",".$amount);
- $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
- $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog);
- $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES);
-
- $items[] = $rrow;
- }
-
- $oTemplate->set ('amount', $amount);
- $oTemplate->set ('count', $count);
- $oTemplate->set ('start', $start);
- $oTemplate->set ('items', $items);
- $oTemplate->template('templates/blocked.html');
- break;
-
- case 'all':
- $start = intRequestVar('start') ? intRequestVar('start') : 0;
- $amount = intRequestVar('amount') ? intRequestVar('amount') : 25;
-
- $rres = mysql_query ("
- SELECT
- COUNT(*) AS count
- FROM
- ".sql_table('plugin_tb')." AS t,
- ".sql_table('item')." AS i
- WHERE
- t.tb_id = i.inumber AND
- t.block = 0
- ");
-
- if ($row = mysql_fetch_array($rres))
- $count = $row['count'];
- else
- $count = 0;
+ $items = array();
+
+ while ($rrow = mysql_fetch_array($rres)){
+ $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50);
+ $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']);
+ $rrow['title'] = htmlspecialchars($rrow['title']);
- $rres = mysql_query ("
- SELECT
- i.ititle AS story,
- i.inumber AS story_id,
- t.id AS id,
- t.title AS title,
- t.blog_name AS blog_name,
- t.excerpt AS excerpt,
- t.url AS url,
- UNIX_TIMESTAMP(t.timestamp) AS timestamp
- FROM
- ".sql_table('plugin_tb')." AS t,
- ".sql_table('item')." AS i
- WHERE
- t.tb_id = i.inumber AND
- t.block = 0
- ORDER BY
- timestamp DESC
- LIMIT
- ".$start.",".$amount."
- ");
-
- $items = array();
-
- while ($rrow = mysql_fetch_array($rres))
- {
- $rrow['title'] = $oPluginAdmin->plugin->_cut_string($rrow['title'], 50);
- $rrow['title'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['title']);
- $rrow['title'] = htmlspecialchars($rrow['title']);
-// $rrow['title'] = _CHARSET == 'UTF-8' ? $rrow['title'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['title']);
-
- $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50);
- $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']);
- $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']);
-// $rrow['blog_name'] = _CHARSET == 'UTF-8' ? $rrow['blog_name'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['blog_name']);
-
- $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800);
- $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']);
- $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']);
-// $rrow['excerpt'] = _CHARSET == 'UTF-8' ? $rrow['excerpt'] : $oPluginAdmin->plugin->_utf8_to_entities($rrow['excerpt']);
-
- $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES);
-
- $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
- $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog);
- $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES);
-
- $items[] = $rrow;
+ $rrow['blog_name'] = $oPluginAdmin->plugin->_cut_string($rrow['blog_name'], 50);
+ $rrow['blog_name'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['blog_name']);
+ $rrow['blog_name'] = htmlspecialchars($rrow['blog_name']);
+
+ $rrow['excerpt'] = $oPluginAdmin->plugin->_cut_string($rrow['excerpt'], 800);
+ $rrow['excerpt'] = $oPluginAdmin->plugin->_strip_controlchar($rrow['excerpt']);
+ $rrow['excerpt'] = htmlspecialchars($rrow['excerpt']);
+
+ $rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES);
+ $rrow['timestamp'] = htmlspecialchars($rrow['timestamp'], ENT_QUOTES);
+
+ $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
+ $rrow['story_url'] = $oPluginAdmin->plugin->_createItemLink($rrow['story_id'], $blog);
+ $rrow['story'] = htmlspecialchars(strip_tags($rrow['story']), ENT_QUOTES);
+
+ $items[] = $rrow;
+ }
+
+ $oTemplate->set('amount', $amount);
+ $oTemplate->set('start', $start);
+ $oTemplate->set('items', $items);
+
+ if( $action == 'all')
+ $oTemplate->template('templates/all.html');
+ else
+ $oTemplate->template('templates/blocked.html');
}
+ break;
- $oTemplate->set ('amount', $amount);
- $oTemplate->set ('count', $count);
- $oTemplate->set ('start', $start);
- $oTemplate->set ('items', $items);
- $oTemplate->template('templates/all.html');
- break;
-
case 'list':
$id = requestVar('id');
$start = intRequestVar('start') ? intRequestVar('start') : 0;
// Create the admin area page
echo $oTemplate->fetch();
- echo '<hr noshade="noshade" size="1" /><div align="right">Powered by <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon</a></div>';
+ echo '<div align="right">Powered by <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon</a></div>';
$oPluginAdmin->end();
-?>
<h3>ÆüËܸìÈǹ¹¿·ÍúÎò</h3>
<ul>
- <li>Version 2.0.3jp7 : (2006/*/*)</li>
+ <li>Version 2.0.3jp8 : (2006/**/**)</li>
+ <li>¡¡[Fixed] ´ÉÍý²èÌ̤ÇStory¤Î¥ê¥ó¥¯¤ÎÉÔ¶ñ¹ç¤ò½¤Àµ</li>
+ <li>¡¡[Changed] URLÃê½Ð¥ë¡¼¥Á¥ó¤ò²þÎÉ</li>
+ <li>¡¡[Changed] ´ÉÍý²èÌ̤ؤΥê¥ó¥¯¤ò½¤Àµ</li>
+ <li>¡¡[Changed] ´ÉÍý²èÌ̤Υڡ¼¥¸¥ó¥°¤òAjaxÂбþ¤Ë¤·¤¿</li>
+ <li>¡¡[Changed] ¥È¥é¥Ã¥¯¥Ð¥Ã¥¯ÄÌÃÎ¥¢¥É¥ì¥¹¤ò¥Ö¥í¥°¤´¤È¤ËÀßÄê¤Ç¤¤ë¤è¤¦¤Ë¤·¤¿</li>
+
+ <li>Version 2.0.3jp7 : (2006/11/26)</li>
<li>¡¡[Changed] SpamChek¤Ë¤Ä¤¤¤ÆÈùÄ´À°</li>
<li>¡¡[Added] Ticket½èÍý¤òÄɲÃ(CSRFÂкö)</li>
<li>¡¡[Fixed] URL¤Ë&¤¬Æþ¤Ã¤Æ¤¤¤ë¤È¤¤ÎÆ°ºî¤òÊѹ¹</li>
+ <li>¡¡[Added] ´ÉÍý²èÌ̤˥¢¥¤¥³¥ó¤òÄɲÃ</li>
<li>Version 2.0.3jp6 : (2006/09/30)</li>
<li>¡¡[Fixed] ¥»¥¥å¥ê¥Æ¥£¤Î¸þ¾å</li>
<table>
<thead>
<tr>
+ <th>Date</th>
<th>Story</th>
<th>Title, Blog and Excerpt</th>
- <th>Date</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<?php while (list(,$item) = each ($items)): ?>
<tr onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
<td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d @ H:i",$item['timestamp']));?>
+ </td>
+ <td>
<a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
</td>
<td>
<?php echo $item['excerpt'];?>
</td>
<td>
- <?php echo str_replace(' ', ' ', date("Y-m-d @ H:i",$item['timestamp']));?>
- </td>
- <td>
<a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=block&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
</td>
<td>
<?php global $manager?>
<h2>Trackback</h2>
+<script type="text/javascript" src="<?php echo $CONF['PluginURL'].'trackback/js/'?>prototype-1.4.0.js"></script>
+<script type="text/javascript" src="<?php echo $CONF['PluginURL'].'trackback/js/'?>rico.js"></script>
<ul>
<li>
<img border="0" src="<?php echo $plugindirurl?>silk/application_view_list.png" />
<img border="0" src="<?php echo $plugindirurl?>silk/plugin_edit.png" />
<a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['AdminURL'].'index.php?action=pluginoptions&plugid='.$plugid),ENT_QUOTES);?>">¥×¥é¥°¥¤¥ó¥ª¥×¥·¥ç¥óÀßÄê</a>
</li>
-</ul>
\ No newline at end of file
+</ul>
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="object" id='tb_grid_updater'>
+ <rows update_ui='true' >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d\nH:i:s",$item['timestamp']));?>
+ </td>
+ <td>
+ <a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
+ </td>
+ <td>
+ <a href="<?php echo $item['url'];?>"><img alt="Visit" border="0" src="<?php echo $plugindirurl?>silk/house_go.png" /></a>
+ <strong><?php echo $item['title'];?></strong><br />
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=block&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=delete&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
+ </td>
+ </tr>
+ <?php endwhile; ?>
+ </rows>
+ </response>
+</ajax-response>
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="object" id='tb_grid_updater'>
+ <rows update_ui='true' >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d\nH:i:s",$item['timestamp']));?>
+ </td>
+ <td>
+ <a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
+ </td>
+ <td>
+ <a href="<?php echo $item['url'];?>"><img alt="Visit" border="0" src="<?php echo $plugindirurl?>silk/house_go.png" /></a>
+ <strong><?php echo $item['title'];?></strong>
+ <?php echo $item['spam'] ?
+ '<img alt="spam" border="0" src="' . $plugindirurl . 'silk/delete.png" />' :
+ '';?>
+ <?php echo $item['link'] ?
+ '' :
+ '<img alt="NOT Linked" border="0" src="' . $plugindirurl . 'silk/link_break.png" />';?>
+ <br />
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=unblock&tb='.$item['id'].'&next=blocked'),ENT_QUOTES);?>"><img alt="Unblock" border="0" src="<?php echo $plugindirurl;?>silk/accept.png" /></a>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=delete&tb='.$item['id'].'&next=blocked'),ENT_QUOTES);?>"><img alt="Delete" border="0" src="<?php echo $plugindirurl;?>silk/cross.png" /></a>
+ </td>
+ </tr>
+ <?php endwhile; ?>
+ </rows>
+ </response>
+</ajax-response>
<h3>日本語版更新履歴</h3>
<ul>
+ <li>Version 2.0.3jp8 : (2006/**/**)</li>
+ <li> [Fixed] 管理画面でStoryのリンクの不具合を修正</li>
+ <li> [Changed] URL抽出ルーチンを改良</li>
+ <li> [Changed] 管理画面へのリンクを修正</li>
+ <li> [Changed] 管理画面のページングをAjax対応にした</li>
+ <li> [Changed] トラックバック通知アドレスをブログごとに設定できるようにした</li>
+
<li>Version 2.0.3jp7 : (2006/11/26)</li>
<li> [Changed] SpamChekについて微調整</li>
<li> [Added] Ticket処理を追加(CSRF対策)</li>
<table>
<thead>
<tr>
+ <th>Date</th>
<th>Story</th>
<th>Title, Blog and Excerpt</th>
- <th>Date</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<?php while (list(,$item) = each ($items)): ?>
<tr onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
<td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d @ H:i",$item['timestamp']));?>
+ </td>
+ <td>
<a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
</td>
<td>
<?php echo $item['excerpt'];?>
</td>
<td>
- <?php echo str_replace(' ', ' ', date("Y-m-d @ H:i",$item['timestamp']));?>
- </td>
- <td>
<a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=block&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
</td>
<td>
--- /dev/null
+<?php global $manager; ?>
+<h2>
+ All trackbacks
+</h2>
+
+<div id="showingLabel"><?php echo $count ; ?>件中 1 - 5 件目を表示しています</div>
+
+<div style="width: 100%">
+<div id="viewPort" style="float:left; width: 420px">
+<table id="tb_grid" style="border:0; margin:0; width: 400px">
+ <thead>
+ <tr>
+ <th style="width:80px">Date</th>
+ <th style="width:120px">Story</th>
+ <th >Title, Blog and Excerpt</th>
+ <th style="width:20px"> </th>
+ <th style="width:20px"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+</div>
+<div style="clear:both"></div>
+
+<script>
+//<![CDATA[
+ function updateHeader( liveGrid, offset ) {
+ $('showingLabel').innerHTML = liveGrid.metaData.getTotalRows() + "件中 " + (offset+1) + " - " + (offset+liveGrid.metaData.getPageSize()) + "件目を表示しています。";
+ }
+
+ function loadGrid() {
+ var width = $('content').offsetWidth
+ $('viewPort').style.width = width + 'px';
+ $('tb_grid').style.width = ( width - 40 ) + 'px';
+
+ var max = <?php echo $count; ?>;
+ var params = ['action=ajax','type=all','ticket=' + '<?php echo $ticket ;?>'];
+ var opts = {
+ prefetchBuffer: true
+ ,prefetchOffset: 50
+ ,onscroll: updateHeader
+ ,requestParameters: params
+ ,sortAscendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_asc.gif'
+ ,sortDescendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_desc.gif'
+ ,columns: [ ["date", true], ["item", true], ["title", true], ["ban", false], ["del", false] ]
+ };
+ var liveGrid = new Rico.LiveGrid('tb_grid',5 , max, '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php', opts);
+ }
+
+ window.onload = loadGrid;
+//]]>
+</script>
--- /dev/null
+<?php global $manager; ?>
+<h2>
+ ブロックされたトラックバック
+</h2>
+
+<ul>
+ <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_clear&next=blocked'),ENT_QUOTES); ?>">ブロックされたトラックバックのクリア</a></li>
+ <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_spamclear&next=blocked'),ENT_QUOTES); ?>">spam判定されたトラックバックのクリア</a></li>
+</ul>
+
+<div id="showingLabel"><?php echo $count ; ?>件中 1 - 5 件目を表示しています</div>
+
+<div style="float:left; width: 100%">
+<div id="viewPort" style="float:left; width: 620px">
+<table id="tb_grid" style="border:0; margin:0; width: 600px">
+ <thead>
+ <tr>
+ <th style="width:80px">Date</th>
+ <th style="width:120px">Story</th>
+ <th >Title, Blog and Excerpt</th>
+ <th style="width:20px"> </th>
+ <th style="width:20px"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+</div>
+<div style="clear:both"></div>
+
+<script>
+//<![CDATA[
+ function updateHeader( liveGrid, offset ) {
+ $('showingLabel').innerHTML = liveGrid.metaData.getTotalRows() + "件中 " + (offset+1) + " - " + (offset+liveGrid.metaData.getPageSize()) + "件目を表示しています。";
+ }
+
+ function loadGrid() {
+ var width = $('content').offsetWidth
+ $('viewPort').style.width = width + 'px';
+ $('tb_grid').style.width = (width - 40) + 'px';
+
+ var max = <?php echo $count; ?>;
+ var params = ['action=ajax','type=blocked','ticket=' + '<?php echo $ticket ;?>'];
+ var opts = {
+ prefetchBuffer: true
+ ,prefetchOffset: 50
+ ,onscroll: updateHeader
+ ,requestParameters: params
+ ,sortAscendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_asc.gif'
+ ,sortDescendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_desc.gif'
+ ,columns: [ ["date", true], ["item", true], ["title", true], ["ban", false], ["del", false] ]
+ };
+ var liveGrid = new Rico.LiveGrid('tb_grid',5 , max, '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php', opts);
+ }
+
+ window.onload = loadGrid;
+//]]>
+</script>
<?php global $manager?>
<h2>Trackback</h2>
+<script type="text/javascript" src="<?php echo $CONF['PluginURL'].'trackback/js/'?>prototype-1.4.0.js"></script>
+<script type="text/javascript" src="<?php echo $CONF['PluginURL'].'trackback/js/'?>rico.js"></script>
<ul>
<li>
<img border="0" src="<?php echo $plugindirurl?>silk/application_view_list.png" />
<img border="0" src="<?php echo $plugindirurl?>silk/plugin_edit.png" />
<a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['AdminURL'].'index.php?action=pluginoptions&plugid='.$plugid),ENT_QUOTES);?>">プラグインオプション設定</a>
</li>
-</ul>
\ No newline at end of file
+</ul>
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="object" id='tb_grid_updater'>
+ <rows update_ui='true' >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d\nH:i:s",$item['timestamp']));?>
+ </td>
+ <td>
+ <a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
+ </td>
+ <td>
+ <a href="<?php echo $item['url'];?>"><img alt="Visit" border="0" src="<?php echo $plugindirurl?>silk/house_go.png" /></a>
+ <strong><?php echo $item['title'];?></strong><br />
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=block&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=delete&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
+ </td>
+ </tr>
+ <?php endwhile; ?>
+ </rows>
+ </response>
+</ajax-response>
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="object" id='tb_grid_updater'>
+ <rows update_ui='true' >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d\nH:i:s",$item['timestamp']));?>
+ </td>
+ <td>
+ <a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
+ </td>
+ <td>
+ <a href="<?php echo $item['url'];?>"><img alt="Visit" border="0" src="<?php echo $plugindirurl?>silk/house_go.png" /></a>
+ <strong><?php echo $item['title'];?></strong>
+ <?php echo $item['spam'] ?
+ '<img alt="spam" border="0" src="' . $plugindirurl . 'silk/delete.png" />' :
+ '';?>
+ <?php echo $item['link'] ?
+ '' :
+ '<img alt="NOT Linked" border="0" src="' . $plugindirurl . 'silk/link_break.png" />';?>
+ <br />
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=unblock&tb='.$item['id'].'&next=blocked'),ENT_QUOTES);?>"><img alt="Unblock" border="0" src="<?php echo $plugindirurl;?>silk/accept.png" /></a>
+ </td>
+ <td>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=delete&tb='.$item['id'].'&next=blocked'),ENT_QUOTES);?>"><img alt="Delete" border="0" src="<?php echo $plugindirurl;?>silk/cross.png" /></a>
+ </td>
+ </tr>
+ <?php endwhile; ?>
+ </rows>
+ </response>
+</ajax-response>
--- /dev/null
+/* Prototype JavaScript framework, version 1.4.0
+ * (c) 2005 Sam Stephenson <sam@conio.net>
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.4.0',
+ ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+
+ emptyFunction: function() {},
+ K: function(x) {return x}
+}
+
+var Class = {
+ create: function() {
+ return function() {
+ this.initialize.apply(this, arguments);
+ }
+ }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+ for (property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+Object.inspect = function(object) {
+ try {
+ if (object == undefined) return 'undefined';
+ if (object == null) return 'null';
+ return object.inspect ? object.inspect() : object.toString();
+ } catch (e) {
+ if (e instanceof RangeError) return '...';
+ throw e;
+ }
+}
+
+Function.prototype.bind = function() {
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function() {
+ return __method.apply(object, args.concat($A(arguments)));
+ }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+ var __method = this;
+ return function(event) {
+ return __method.call(object, event || window.event);
+ }
+}
+
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ var digits = this.toString(16);
+ if (this < 16) return '0' + digits;
+ return digits;
+ },
+
+ succ: function() {
+ return this + 1;
+ },
+
+ times: function(iterator) {
+ $R(0, this, true).each(iterator);
+ return this;
+ }
+});
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0; i < arguments.length; i++) {
+ var lambda = arguments[i];
+ try {
+ returnValue = lambda();
+ break;
+ } catch (e) {}
+ }
+
+ return returnValue;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+ initialize: function(callback, frequency) {
+ this.callback = callback;
+ this.frequency = frequency;
+ this.currentlyExecuting = false;
+
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.callback();
+ } finally {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+function $() {
+ var elements = new Array();
+
+ for (var i = 0; i < arguments.length; i++) {
+ var element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+
+ if (arguments.length == 1)
+ return element;
+
+ elements.push(element);
+ }
+
+ return elements;
+}
+Object.extend(String.prototype, {
+ stripTags: function() {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ },
+
+ stripScripts: function() {
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+ },
+
+ extractScripts: function() {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ return (this.match(matchAll) || []).map(function(scriptTag) {
+ return (scriptTag.match(matchOne) || ['', ''])[1];
+ });
+ },
+
+ evalScripts: function() {
+ return this.extractScripts().map(eval);
+ },
+
+ escapeHTML: function() {
+ var div = document.createElement('div');
+ var text = document.createTextNode(this);
+ div.appendChild(text);
+ return div.innerHTML;
+ },
+
+ unescapeHTML: function() {
+ var div = document.createElement('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+ },
+
+ toQueryParams: function() {
+ var pairs = this.match(/^\??(.*)$/)[1].split('&');
+ return pairs.inject({}, function(params, pairString) {
+ var pair = pairString.split('=');
+ params[pair[0]] = pair[1];
+ return params;
+ });
+ },
+
+ toArray: function() {
+ return this.split('');
+ },
+
+ camelize: function() {
+ var oStringList = this.split('-');
+ if (oStringList.length == 1) return oStringList[0];
+
+ var camelizedString = this.indexOf('-') == 0
+ ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
+ : oStringList[0];
+
+ for (var i = 1, len = oStringList.length; i < len; i++) {
+ var s = oStringList[i];
+ camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
+ }
+
+ return camelizedString;
+ },
+
+ inspect: function() {
+ return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
+ }
+});
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var $break = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+ each: function(iterator) {
+ var index = 0;
+ try {
+ this._each(function(value) {
+ try {
+ iterator(value, index++);
+ } catch (e) {
+ if (e != $continue) throw e;
+ }
+ });
+ } catch (e) {
+ if (e != $break) throw e;
+ }
+ },
+
+ all: function(iterator) {
+ var result = true;
+ this.each(function(value, index) {
+ result = result && !!(iterator || Prototype.K)(value, index);
+ if (!result) throw $break;
+ });
+ return result;
+ },
+
+ any: function(iterator) {
+ var result = true;
+ this.each(function(value, index) {
+ if (result = !!(iterator || Prototype.K)(value, index))
+ throw $break;
+ });
+ return result;
+ },
+
+ collect: function(iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
+
+ detect: function (iterator) {
+ var result;
+ this.each(function(value, index) {
+ if (iterator(value, index)) {
+ result = value;
+ throw $break;
+ }
+ });
+ return result;
+ },
+
+ findAll: function(iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ if (iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
+
+ grep: function(pattern, iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ var stringValue = value.toString();
+ if (stringValue.match(pattern))
+ results.push((iterator || Prototype.K)(value, index));
+ })
+ return results;
+ },
+
+ include: function(object) {
+ var found = false;
+ this.each(function(value) {
+ if (value == object) {
+ found = true;
+ throw $break;
+ }
+ });
+ return found;
+ },
+
+ inject: function(memo, iterator) {
+ this.each(function(value, index) {
+ memo = iterator(memo, value, index);
+ });
+ return memo;
+ },
+
+ invoke: function(method) {
+ var args = $A(arguments).slice(1);
+ return this.collect(function(value) {
+ return value[method].apply(value, args);
+ });
+ },
+
+ max: function(iterator) {
+ var result;
+ this.each(function(value, index) {
+ value = (iterator || Prototype.K)(value, index);
+ if (value >= (result || value))
+ result = value;
+ });
+ return result;
+ },
+
+ min: function(iterator) {
+ var result;
+ this.each(function(value, index) {
+ value = (iterator || Prototype.K)(value, index);
+ if (value <= (result || value))
+ result = value;
+ });
+ return result;
+ },
+
+ partition: function(iterator) {
+ var trues = [], falses = [];
+ this.each(function(value, index) {
+ ((iterator || Prototype.K)(value, index) ?
+ trues : falses).push(value);
+ });
+ return [trues, falses];
+ },
+
+ pluck: function(property) {
+ var results = [];
+ this.each(function(value, index) {
+ results.push(value[property]);
+ });
+ return results;
+ },
+
+ reject: function(iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ if (!iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
+
+ sortBy: function(iterator) {
+ return this.collect(function(value, index) {
+ return {value: value, criteria: iterator(value, index)};
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }).pluck('value');
+ },
+
+ toArray: function() {
+ return this.collect(Prototype.K);
+ },
+
+ zip: function() {
+ var iterator = Prototype.K, args = $A(arguments);
+ if (typeof args.last() == 'function')
+ iterator = args.pop();
+
+ var collections = [this].concat(args).map($A);
+ return this.map(function(value, index) {
+ iterator(value = collections.pluck(index));
+ return value;
+ });
+ },
+
+ inspect: function() {
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
+ }
+}
+
+Object.extend(Enumerable, {
+ map: Enumerable.collect,
+ find: Enumerable.detect,
+ select: Enumerable.findAll,
+ member: Enumerable.include,
+ entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) {
+ return iterable.toArray();
+ } else {
+ var results = [];
+ for (var i = 0; i < iterable.length; i++)
+ results.push(iterable[i]);
+ return results;
+ }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+ _each: function(iterator) {
+ for (var i = 0; i < this.length; i++)
+ iterator(this[i]);
+ },
+
+ clear: function() {
+ this.length = 0;
+ return this;
+ },
+
+ first: function() {
+ return this[0];
+ },
+
+ last: function() {
+ return this[this.length - 1];
+ },
+
+ compact: function() {
+ return this.select(function(value) {
+ return value != undefined || value != null;
+ });
+ },
+
+ flatten: function() {
+ return this.inject([], function(array, value) {
+ return array.concat(value.constructor == Array ?
+ value.flatten() : [value]);
+ });
+ },
+
+ without: function() {
+ var values = $A(arguments);
+ return this.select(function(value) {
+ return !values.include(value);
+ });
+ },
+
+ indexOf: function(object) {
+ for (var i = 0; i < this.length; i++)
+ if (this[i] == object) return i;
+ return -1;
+ },
+
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ shift: function() {
+ var result = this[0];
+ for (var i = 0; i < this.length - 1; i++)
+ this[i] = this[i + 1];
+ this.length--;
+ return result;
+ },
+
+ inspect: function() {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ }
+});
+var Hash = {
+ _each: function(iterator) {
+ for (key in this) {
+ var value = this[key];
+ if (typeof value == 'function') continue;
+
+ var pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+ },
+
+ keys: function() {
+ return this.pluck('key');
+ },
+
+ values: function() {
+ return this.pluck('value');
+ },
+
+ merge: function(hash) {
+ return $H(hash).inject($H(this), function(mergedHash, pair) {
+ mergedHash[pair.key] = pair.value;
+ return mergedHash;
+ });
+ },
+
+ toQueryString: function() {
+ return this.map(function(pair) {
+ return pair.map(encodeURIComponent).join('=');
+ }).join('&');
+ },
+
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ }
+}
+
+function $H(object) {
+ var hash = Object.extend({}, object || {});
+ Object.extend(hash, Enumerable);
+ Object.extend(hash, Hash);
+ return hash;
+}
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+ initialize: function(start, end, exclusive) {
+ this.start = start;
+ this.end = end;
+ this.exclusive = exclusive;
+ },
+
+ _each: function(iterator) {
+ var value = this.start;
+ do {
+ iterator(value);
+ value = value.succ();
+ } while (this.include(value));
+ },
+
+ include: function(value) {
+ if (value < this.start)
+ return false;
+ if (this.exclusive)
+ return value < this.end;
+ return value <= this.end;
+ }
+});
+
+var $R = function(start, end, exclusive) {
+ return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+ getTransport: function() {
+ return Try.these(
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')},
+ function() {return new XMLHttpRequest()}
+ ) || false;
+ },
+
+ activeRequestCount: 0
+}
+
+Ajax.Responders = {
+ responders: [],
+
+ _each: function(iterator) {
+ this.responders._each(iterator);
+ },
+
+ register: function(responderToAdd) {
+ if (!this.include(responderToAdd))
+ this.responders.push(responderToAdd);
+ },
+
+ unregister: function(responderToRemove) {
+ this.responders = this.responders.without(responderToRemove);
+ },
+
+ dispatch: function(callback, request, transport, json) {
+ this.each(function(responder) {
+ if (responder[callback] && typeof responder[callback] == 'function') {
+ try {
+ responder[callback].apply(responder, [request, transport, json]);
+ } catch (e) {}
+ }
+ });
+ }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+ onCreate: function() {
+ Ajax.activeRequestCount++;
+ },
+
+ onComplete: function() {
+ Ajax.activeRequestCount--;
+ }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+ setOptions: function(options) {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ parameters: ''
+ }
+ Object.extend(this.options, options || {});
+ },
+
+ responseIsSuccess: function() {
+ return this.transport.status == undefined
+ || this.transport.status == 0
+ || (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ responseIsFailure: function() {
+ return !this.responseIsSuccess();
+ }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ initialize: function(url, options) {
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+ this.request(url);
+ },
+
+ request: function(url) {
+ var parameters = this.options.parameters || '';
+ if (parameters.length > 0) parameters += '&_=';
+
+ try {
+ this.url = url;
+ if (this.options.method == 'get' && parameters.length > 0)
+ this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+ this.transport.open(this.options.method, this.url,
+ this.options.asynchronous);
+
+ if (this.options.asynchronous) {
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
+ }
+
+ this.setRequestHeaders();
+
+ var body = this.options.postBody ? this.options.postBody : parameters;
+ this.transport.send(this.options.method == 'post' ? body : null);
+
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ setRequestHeaders: function() {
+ var requestHeaders =
+ ['X-Requested-With', 'XMLHttpRequest',
+ 'X-Prototype-Version', Prototype.Version];
+
+ if (this.options.method == 'post') {
+ requestHeaders.push('Content-type',
+ 'application/x-www-form-urlencoded');
+
+ /* Force "Connection: close" for Mozilla browsers to work around
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
+ * header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType)
+ requestHeaders.push('Connection', 'close');
+ }
+
+ if (this.options.requestHeaders)
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
+
+ for (var i = 0; i < requestHeaders.length; i += 2)
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
+ },
+
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState != 1)
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ header: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) {}
+ },
+
+ evalJSON: function() {
+ try {
+ return eval(this.header('X-JSON'));
+ } catch (e) {}
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ respondToReadyState: function(readyState) {
+ var event = Ajax.Request.Events[readyState];
+ var transport = this.transport, json = this.evalJSON();
+
+ if (event == 'Complete') {
+ try {
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if ((this.header('Content-type') || '').match(/^text\/javascript/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
+ if (event == 'Complete')
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ },
+
+ dispatchException: function(exception) {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
+ }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+ initialize: function(container, url, options) {
+ this.containers = {
+ success: container.success ? $(container.success) : $(container),
+ failure: container.failure ? $(container.failure) :
+ (container.success ? null : $(container))
+ }
+
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
+ this.options.onComplete = (function(transport, object) {
+ this.updateContent();
+ onComplete(transport, object);
+ }).bind(this);
+
+ this.request(url);
+ },
+
+ updateContent: function() {
+ var receiver = this.responseIsSuccess() ?
+ this.containers.success : this.containers.failure;
+ var response = this.transport.responseText;
+
+ if (!this.options.evalScripts)
+ response = response.stripScripts();
+
+ if (receiver) {
+ if (this.options.insertion) {
+ new this.options.insertion(receiver, response);
+ } else {
+ Element.update(receiver, response);
+ }
+ }
+
+ if (this.responseIsSuccess()) {
+ if (this.onComplete)
+ setTimeout(this.onComplete.bind(this), 10);
+ }
+ }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+ initialize: function(container, url, options) {
+ this.setOptions(options);
+ this.onComplete = this.options.onComplete;
+
+ this.frequency = (this.options.frequency || 2);
+ this.decay = (this.options.decay || 1);
+
+ this.updater = {};
+ this.container = container;
+ this.url = url;
+
+ this.start();
+ },
+
+ start: function() {
+ this.options.onComplete = this.updateComplete.bind(this);
+ this.onTimerEvent();
+ },
+
+ stop: function() {
+ this.updater.onComplete = undefined;
+ clearTimeout(this.timer);
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ },
+
+ updateComplete: function(request) {
+ if (this.options.decay) {
+ this.decay = (request.responseText == this.lastText ?
+ this.decay * this.options.decay : 1);
+
+ this.lastText = request.responseText;
+ }
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
+ this.decay * this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
+ }
+});
+document.getElementsByClassName = function(className, parentElement) {
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ return $A(children).inject([], function(elements, child) {
+ if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ elements.push(child);
+ return elements;
+ });
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element) {
+ var Element = new Object();
+}
+
+Object.extend(Element, {
+ visible: function(element) {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ }
+ },
+
+ hide: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display = 'none';
+ }
+ },
+
+ show: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display = '';
+ }
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ },
+
+ update: function(element, html) {
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function() {html.evalScripts()}, 10);
+ },
+
+ getHeight: function(element) {
+ element = $(element);
+ return element.offsetHeight;
+ },
+
+ classNames: function(element) {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return Element.classNames(element).include(className);
+ },
+
+ addClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return Element.classNames(element).add(className);
+ },
+
+ removeClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return Element.classNames(element).remove(className);
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ element = $(element);
+ for (var i = 0; i < element.childNodes.length; i++) {
+ var node = element.childNodes[i];
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ Element.remove(node);
+ }
+ },
+
+ empty: function(element) {
+ return $(element).innerHTML.match(/^\s*$/);
+ },
+
+ scrollTo: function(element) {
+ element = $(element);
+ var x = element.x ? element.x : element.offsetLeft,
+ y = element.y ? element.y : element.offsetTop;
+ window.scrollTo(x, y);
+ },
+
+ getStyle: function(element, style) {
+ element = $(element);
+ var value = element.style[style.camelize()];
+ if (!value) {
+ if (document.defaultView && document.defaultView.getComputedStyle) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css.getPropertyValue(style) : null;
+ } else if (element.currentStyle) {
+ value = element.currentStyle[style.camelize()];
+ }
+ }
+
+ if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+ if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+
+ return value == 'auto' ? null : value;
+ },
+
+ setStyle: function(element, style) {
+ element = $(element);
+ for (name in style)
+ element.style[name.camelize()] = style[name];
+ },
+
+ getDimensions: function(element) {
+ element = $(element);
+ if (Element.getStyle(element, 'display') != 'none')
+ return {width: element.offsetWidth, height: element.offsetHeight};
+
+ // All *Width and *Height properties give 0 on elements with display none,
+ // so enable the element temporarily
+ var els = element.style;
+ var originalVisibility = els.visibility;
+ var originalPosition = els.position;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = '';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = 'none';
+ els.position = originalPosition;
+ els.visibility = originalVisibility;
+ return {width: originalWidth, height: originalHeight};
+ },
+
+ makePositioned: function(element) {
+ element = $(element);
+ var pos = Element.getStyle(element, 'position');
+ if (pos == 'static' || !pos) {
+ element._madePositioned = true;
+ element.style.position = 'relative';
+ // Opera returns the offset relative to the positioning context, when an
+ // element is position relative but top and left have not been defined
+ if (window.opera) {
+ element.style.top = 0;
+ element.style.left = 0;
+ }
+ }
+ },
+
+ undoPositioned: function(element) {
+ element = $(element);
+ if (element._madePositioned) {
+ element._madePositioned = undefined;
+ element.style.position =
+ element.style.top =
+ element.style.left =
+ element.style.bottom =
+ element.style.right = '';
+ }
+ },
+
+ makeClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return;
+ element._overflow = element.style.overflow;
+ if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+ element.style.overflow = 'hidden';
+ },
+
+ undoClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return;
+ element.style.overflow = element._overflow;
+ element._overflow = undefined;
+ }
+});
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+ this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+ initialize: function(element, content) {
+ this.element = $(element);
+ this.content = content.stripScripts();
+
+ if (this.adjacency && this.element.insertAdjacentHTML) {
+ try {
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
+ } catch (e) {
+ if (this.element.tagName.toLowerCase() == 'tbody') {
+ this.insertContent(this.contentFromAnonymousTable());
+ } else {
+ throw e;
+ }
+ }
+ } else {
+ this.range = this.element.ownerDocument.createRange();
+ if (this.initializeRange) this.initializeRange();
+ this.insertContent([this.range.createContextualFragment(this.content)]);
+ }
+
+ setTimeout(function() {content.evalScripts()}, 10);
+ },
+
+ contentFromAnonymousTable: function() {
+ var div = document.createElement('div');
+ div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+ return $A(div.childNodes[0].childNodes[0].childNodes);
+ }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+ initializeRange: function() {
+ this.range.setStartBefore(this.element);
+ },
+
+ insertContent: function(fragments) {
+ fragments.each((function(fragment) {
+ this.element.parentNode.insertBefore(fragment, this.element);
+ }).bind(this));
+ }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+ initializeRange: function() {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(true);
+ },
+
+ insertContent: function(fragments) {
+ fragments.reverse(false).each((function(fragment) {
+ this.element.insertBefore(fragment, this.element.firstChild);
+ }).bind(this));
+ }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+ initializeRange: function() {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(this.element);
+ },
+
+ insertContent: function(fragments) {
+ fragments.each((function(fragment) {
+ this.element.appendChild(fragment);
+ }).bind(this));
+ }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+ initializeRange: function() {
+ this.range.setStartAfter(this.element);
+ },
+
+ insertContent: function(fragments) {
+ fragments.each((function(fragment) {
+ this.element.parentNode.insertBefore(fragment,
+ this.element.nextSibling);
+ }).bind(this));
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+ initialize: function(element) {
+ this.element = $(element);
+ },
+
+ _each: function(iterator) {
+ this.element.className.split(/\s+/).select(function(name) {
+ return name.length > 0;
+ })._each(iterator);
+ },
+
+ set: function(className) {
+ this.element.className = className;
+ },
+
+ add: function(classNameToAdd) {
+ if (this.include(classNameToAdd)) return;
+ this.set(this.toArray().concat(classNameToAdd).join(' '));
+ },
+
+ remove: function(classNameToRemove) {
+ if (!this.include(classNameToRemove)) return;
+ this.set(this.select(function(className) {
+ return className != classNameToRemove;
+ }).join(' '));
+ },
+
+ toString: function() {
+ return this.toArray().join(' ');
+ }
+}
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Field = {
+ clear: function() {
+ for (var i = 0; i < arguments.length; i++)
+ $(arguments[i]).value = '';
+ },
+
+ focus: function(element) {
+ $(element).focus();
+ },
+
+ present: function() {
+ for (var i = 0; i < arguments.length; i++)
+ if ($(arguments[i]).value == '') return false;
+ return true;
+ },
+
+ select: function(element) {
+ $(element).select();
+ },
+
+ activate: function(element) {
+ element = $(element);
+ element.focus();
+ if (element.select)
+ element.select();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Form = {
+ serialize: function(form) {
+ var elements = Form.getElements($(form));
+ var queryComponents = new Array();
+
+ for (var i = 0; i < elements.length; i++) {
+ var queryComponent = Form.Element.serialize(elements[i]);
+ if (queryComponent)
+ queryComponents.push(queryComponent);
+ }
+
+ return queryComponents.join('&');
+ },
+
+ getElements: function(form) {
+ form = $(form);
+ var elements = new Array();
+
+ for (tagName in Form.Element.Serializers) {
+ var tagElements = form.getElementsByTagName(tagName);
+ for (var j = 0; j < tagElements.length; j++)
+ elements.push(tagElements[j]);
+ }
+ return elements;
+ },
+
+ getInputs: function(form, typeName, name) {
+ form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if (!typeName && !name)
+ return inputs;
+
+ var matchingInputs = new Array();
+ for (var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ if ((typeName && input.type != typeName) ||
+ (name && input.name != name))
+ continue;
+ matchingInputs.push(input);
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function(form) {
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.blur();
+ element.disabled = 'true';
+ }
+ },
+
+ enable: function(form) {
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.disabled = '';
+ }
+ },
+
+ findFirstElement: function(form) {
+ return Form.getElements(form).find(function(element) {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
+ focusFirstElement: function(form) {
+ Field.activate(Form.findFirstElement(form));
+ },
+
+ reset: function(form) {
+ $(form).reset();
+ }
+}
+
+Form.Element = {
+ serialize: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if (parameter) {
+ var key = encodeURIComponent(parameter[0]);
+ if (key.length == 0) return;
+
+ if (parameter[1].constructor != Array)
+ parameter[1] = [parameter[1]];
+
+ return parameter[1].map(function(value) {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
+ },
+
+ getValue: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if (parameter)
+ return parameter[1];
+ }
+}
+
+Form.Element.Serializers = {
+ input: function(element) {
+ switch (element.type.toLowerCase()) {
+ case 'submit':
+ case 'hidden':
+ case 'password':
+ case 'text':
+ return Form.Element.Serializers.textarea(element);
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element);
+ }
+ return false;
+ },
+
+ inputSelector: function(element) {
+ if (element.checked)
+ return [element.name, element.value];
+ },
+
+ textarea: function(element) {
+ return [element.name, element.value];
+ },
+
+ select: function(element) {
+ return Form.Element.Serializers[element.type == 'select-one' ?
+ 'selectOne' : 'selectMany'](element);
+ },
+
+ selectOne: function(element) {
+ var value = '', opt, index = element.selectedIndex;
+ if (index >= 0) {
+ opt = element.options[index];
+ value = opt.value;
+ if (!value && !('value' in opt))
+ value = opt.text;
+ }
+ return [element.name, value];
+ },
+
+ selectMany: function(element) {
+ var value = new Array();
+ for (var i = 0; i < element.length; i++) {
+ var opt = element.options[i];
+ if (opt.selected) {
+ var optValue = opt.value;
+ if (!optValue && !('value' in opt))
+ optValue = opt.text;
+ value.push(optValue);
+ }
+ }
+ return [element.name, value];
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+ initialize: function(element, frequency, callback) {
+ this.frequency = frequency;
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+ initialize: function(element, callback) {
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ if (this.element.tagName.toLowerCase() == 'form')
+ this.registerFormCallbacks();
+ else
+ this.registerCallback(this.element);
+ },
+
+ onElementEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ },
+
+ registerFormCallbacks: function() {
+ var elements = Form.getElements(this.element);
+ for (var i = 0; i < elements.length; i++)
+ this.registerCallback(elements[i]);
+ },
+
+ registerCallback: function(element) {
+ if (element.type) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
+ break;
+ case 'password':
+ case 'text':
+ case 'textarea':
+ case 'select-one':
+ case 'select-multiple':
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
+ break;
+ }
+ }
+ }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+if (!window.Event) {
+ var Event = new Object();
+}
+
+Object.extend(Event, {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+
+ element: function(event) {
+ return event.target || event.srcElement;
+ },
+
+ isLeftClick: function(event) {
+ return (((event.which) && (event.which == 1)) ||
+ ((event.button) && (event.button == 1)));
+ },
+
+ pointerX: function(event) {
+ return event.pageX || (event.clientX +
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
+ },
+
+ pointerY: function(event) {
+ return event.pageY || (event.clientY +
+ (document.documentElement.scrollTop || document.body.scrollTop));
+ },
+
+ stop: function(event) {
+ if (event.preventDefault) {
+ event.preventDefault();
+ event.stopPropagation();
+ } else {
+ event.returnValue = false;
+ event.cancelBubble = true;
+ }
+ },
+
+ // find the first node with the given tagName, starting from the
+ // node the event was triggered on; traverses the DOM upwards
+ findElement: function(event, tagName) {
+ var element = Event.element(event);
+ while (element.parentNode && (!element.tagName ||
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
+ element = element.parentNode;
+ return element;
+ },
+
+ observers: false,
+
+ _observeAndCache: function(element, name, observer, useCapture) {
+ if (!this.observers) this.observers = [];
+ if (element.addEventListener) {
+ this.observers.push([element, name, observer, useCapture]);
+ element.addEventListener(name, observer, useCapture);
+ } else if (element.attachEvent) {
+ this.observers.push([element, name, observer, useCapture]);
+ element.attachEvent('on' + name, observer);
+ }
+ },
+
+ unloadCache: function() {
+ if (!Event.observers) return;
+ for (var i = 0; i < Event.observers.length; i++) {
+ Event.stopObserving.apply(this, Event.observers[i]);
+ Event.observers[i][0] = null;
+ }
+ Event.observers = false;
+ },
+
+ observe: function(element, name, observer, useCapture) {
+ var element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+ || element.attachEvent))
+ name = 'keydown';
+
+ this._observeAndCache(element, name, observer, useCapture);
+ },
+
+ stopObserving: function(element, name, observer, useCapture) {
+ var element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+ || element.detachEvent))
+ name = 'keydown';
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, observer, useCapture);
+ } else if (element.detachEvent) {
+ element.detachEvent('on' + name, observer);
+ }
+ }
+});
+
+/* prevent memory leaks in IE */
+Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+ // set to true if needed, warning: firefox performance problems
+ // NOT neeeded for page scrolling, only if draggable contained in
+ // scrollable elements
+ includeScrollOffsets: false,
+
+ // must be called before calling withinIncludingScrolloffset, every time the
+ // page is scrolled
+ prepare: function() {
+ this.deltaX = window.pageXOffset
+ || document.documentElement.scrollLeft
+ || document.body.scrollLeft
+ || 0;
+ this.deltaY = window.pageYOffset
+ || document.documentElement.scrollTop
+ || document.body.scrollTop
+ || 0;
+ },
+
+ realOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ cumulativeOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ positionedOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ p = Element.getStyle(element, 'position');
+ if (p == 'relative' || p == 'absolute') break;
+ }
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ offsetParent: function(element) {
+ if (element.offsetParent) return element.offsetParent;
+ if (element == document.body) return element;
+
+ while ((element = element.parentNode) && element != document.body)
+ if (Element.getStyle(element, 'position') != 'static')
+ return element;
+
+ return document.body;
+ },
+
+ // caches x/y coordinate pair to use with overlap
+ within: function(element, x, y) {
+ if (this.includeScrollOffsets)
+ return this.withinIncludingScrolloffsets(element, x, y);
+ this.xcomp = x;
+ this.ycomp = y;
+ this.offset = this.cumulativeOffset(element);
+
+ return (y >= this.offset[1] &&
+ y < this.offset[1] + element.offsetHeight &&
+ x >= this.offset[0] &&
+ x < this.offset[0] + element.offsetWidth);
+ },
+
+ withinIncludingScrolloffsets: function(element, x, y) {
+ var offsetcache = this.realOffset(element);
+
+ this.xcomp = x + offsetcache[0] - this.deltaX;
+ this.ycomp = y + offsetcache[1] - this.deltaY;
+ this.offset = this.cumulativeOffset(element);
+
+ return (this.ycomp >= this.offset[1] &&
+ this.ycomp < this.offset[1] + element.offsetHeight &&
+ this.xcomp >= this.offset[0] &&
+ this.xcomp < this.offset[0] + element.offsetWidth);
+ },
+
+ // within must be called directly before
+ overlap: function(mode, element) {
+ if (!mode) return 0;
+ if (mode == 'vertical')
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+ element.offsetHeight;
+ if (mode == 'horizontal')
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+ element.offsetWidth;
+ },
+
+ clone: function(source, target) {
+ source = $(source);
+ target = $(target);
+ target.style.position = 'absolute';
+ var offsets = this.cumulativeOffset(source);
+ target.style.top = offsets[1] + 'px';
+ target.style.left = offsets[0] + 'px';
+ target.style.width = source.offsetWidth + 'px';
+ target.style.height = source.offsetHeight + 'px';
+ },
+
+ page: function(forElement) {
+ var valueT = 0, valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if (element.offsetParent==document.body)
+ if (Element.getStyle(element,'position')=='absolute') break;
+
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ } while (element = element.parentNode);
+
+ return [valueL, valueT];
+ },
+
+ clone: function(source, target) {
+ var options = Object.extend({
+ setLeft: true,
+ setTop: true,
+ setWidth: true,
+ setHeight: true,
+ offsetTop: 0,
+ offsetLeft: 0
+ }, arguments[2] || {})
+
+ // find page position of source
+ source = $(source);
+ var p = Position.page(source);
+
+ // find coordinate system to use
+ target = $(target);
+ var delta = [0, 0];
+ var parent = null;
+ // delta [0,0] will do fine with position: fixed elements,
+ // position:absolute needs offsetParent deltas
+ if (Element.getStyle(target,'position') == 'absolute') {
+ parent = Position.offsetParent(target);
+ delta = Position.page(parent);
+ }
+
+ // correct by body offsets (fixes Safari)
+ if (parent == document.body) {
+ delta[0] -= document.body.offsetLeft;
+ delta[1] -= document.body.offsetTop;
+ }
+
+ // set position
+ if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
+ if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
+ if(options.setWidth) target.style.width = source.offsetWidth + 'px';
+ if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+ },
+
+ absolutize: function(element) {
+ element = $(element);
+ if (element.style.position == 'absolute') return;
+ Position.prepare();
+
+ var offsets = Position.positionedOffset(element);
+ var top = offsets[1];
+ var left = offsets[0];
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ element._originalLeft = left - parseFloat(element.style.left || 0);
+ element._originalTop = top - parseFloat(element.style.top || 0);
+ element._originalWidth = element.style.width;
+ element._originalHeight = element.style.height;
+
+ element.style.position = 'absolute';
+ element.style.top = top + 'px';;
+ element.style.left = left + 'px';;
+ element.style.width = width + 'px';;
+ element.style.height = height + 'px';;
+ },
+
+ relativize: function(element) {
+ element = $(element);
+ if (element.style.position == 'relative') return;
+ Position.prepare();
+
+ element.style.position = 'relative';
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.height = element._originalHeight;
+ element.style.width = element._originalWidth;
+ }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned. For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+ Position.cumulativeOffset = function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == document.body)
+ if (Element.getStyle(element, 'position') == 'absolute') break;
+
+ element = element.offsetParent;
+ } while (element);
+
+ return [valueL, valueT];
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ * Copyright 2005 Sabre Airline Solutions
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ **/
+
+
+//-------------------- rico.js
+var Rico = {
+ Version: '1.1.2',
+ prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
+}
+
+if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3)
+ throw("Rico requires the Prototype JavaScript framework >= 1.3");
+
+Rico.ArrayExtensions = new Array();
+
+if (Object.prototype.extend) {
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}else{
+ Object.prototype.extend = function(object) {
+ return Object.extend.apply(this, [this, object]);
+ }
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
+}
+
+if (Array.prototype.push) {
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
+}
+
+if (!Array.prototype.remove) {
+ Array.prototype.remove = function(dx) {
+ if( isNaN(dx) || dx > this.length )
+ return false;
+ for( var i=0,n=0; i<this.length; i++ )
+ if( i != dx )
+ this[n++]=this[i];
+ this.length-=1;
+ };
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
+}
+
+if (!Array.prototype.removeItem) {
+ Array.prototype.removeItem = function(item) {
+ for ( var i = 0 ; i < this.length ; i++ )
+ if ( this[i] == item ) {
+ this.remove(i);
+ break;
+ }
+ };
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
+}
+
+if (!Array.prototype.indices) {
+ Array.prototype.indices = function() {
+ var indexArray = new Array();
+ for ( index in this ) {
+ var ignoreThis = false;
+ for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
+ if ( this[index] == Rico.ArrayExtensions[i] ) {
+ ignoreThis = true;
+ break;
+ }
+ }
+ if ( !ignoreThis )
+ indexArray[ indexArray.length ] = index;
+ }
+ return indexArray;
+ }
+ Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
+}
+
+// Create the loadXML method and xml getter for Mozilla
+if ( window.DOMParser &&
+ window.XMLSerializer &&
+ window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {
+
+ if (!Document.prototype.loadXML) {
+ Document.prototype.loadXML = function (s) {
+ var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
+ while (this.hasChildNodes())
+ this.removeChild(this.lastChild);
+
+ for (var i = 0; i < doc2.childNodes.length; i++) {
+ this.appendChild(this.importNode(doc2.childNodes[i], true));
+ }
+ };
+ }
+
+ Document.prototype.__defineGetter__( "xml",
+ function () {
+ return (new XMLSerializer()).serializeToString(this);
+ }
+ );
+}
+
+document.getElementsByTagAndClassName = function(tagName, className) {
+ if ( tagName == null )
+ tagName = '*';
+
+ var children = document.getElementsByTagName(tagName) || document.all;
+ var elements = new Array();
+
+ if ( className == null )
+ return children;
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var classNames = child.className.split(' ');
+ for (var j = 0; j < classNames.length; j++) {
+ if (classNames[j] == className) {
+ elements.push(child);
+ break;
+ }
+ }
+ }
+
+ return elements;
+}
+
+
+//-------------------- ricoAccordion.js
+Rico.Accordion = Class.create();
+
+Rico.Accordion.prototype = {
+
+ initialize: function(container, options) {
+ this.container = $(container);
+ this.lastExpandedTab = null;
+ this.accordionTabs = new Array();
+ this.setOptions(options);
+ this._attachBehaviors();
+ if(!container) return;
+
+ this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
+ // validate onloadShowTab
+ if (this.options.onLoadShowTab >= this.accordionTabs.length)
+ this.options.onLoadShowTab = 0;
+
+ // set the initial visual state...
+ for ( var i=0 ; i < this.accordionTabs.length ; i++ )
+ {
+ if (i != this.options.onLoadShowTab){
+ this.accordionTabs[i].collapse();
+ this.accordionTabs[i].content.style.display = 'none';
+ }
+ }
+ this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab];
+ if (this.options.panelHeight == 'auto'){
+ var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0;
+ var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height'));
+ if (isNaN(titleBarSize))
+ titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight;
+
+ var totalTitleBarSize = this.accordionTabs.length * titleBarSize;
+ var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height'));
+ if (isNaN(parentHeight))
+ parentHeight = this.container.parentNode.offsetHeight;
+
+ this.options.panelHeight = parentHeight - totalTitleBarSize-2;
+ }
+
+ this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
+ this.lastExpandedTab.showExpanded();
+ this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
+
+ },
+
+ setOptions: function(options) {
+ this.options = {
+ expandedBg : '#63699c',
+ hoverBg : '#63699c',
+ collapsedBg : '#6b79a5',
+ expandedTextColor : '#ffffff',
+ expandedFontWeight : 'bold',
+ hoverTextColor : '#ffffff',
+ collapsedTextColor : '#ced7ef',
+ collapsedFontWeight : 'normal',
+ hoverTextColor : '#ffffff',
+ borderColor : '#1f669b',
+ panelHeight : 200,
+ onHideTab : null,
+ onShowTab : null,
+ onLoadShowTab : 0
+ }
+ Object.extend(this.options, options || {});
+ },
+
+ showTabByIndex: function( anIndex, animate ) {
+ var doAnimate = arguments.length == 1 ? true : animate;
+ this.showTab( this.accordionTabs[anIndex], doAnimate );
+ },
+
+ showTab: function( accordionTab, animate ) {
+ if ( this.lastExpandedTab == accordionTab )
+ return;
+
+ var doAnimate = arguments.length == 1 ? true : animate;
+
+ if ( this.options.onHideTab )
+ this.options.onHideTab(this.lastExpandedTab);
+
+ this.lastExpandedTab.showCollapsed();
+ var accordion = this;
+ var lastExpandedTab = this.lastExpandedTab;
+
+ this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
+ accordionTab.content.style.display = '';
+
+ accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;
+
+ if ( doAnimate ) {
+ new Rico.Effect.AccordionSize( this.lastExpandedTab.content,
+ accordionTab.content,
+ 1,
+ this.options.panelHeight,
+ 100, 10,
+ { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
+ this.lastExpandedTab = accordionTab;
+ }
+ else {
+ this.lastExpandedTab.content.style.height = "1px";
+ accordionTab.content.style.height = this.options.panelHeight + "px";
+ this.lastExpandedTab = accordionTab;
+ this.showTabDone(lastExpandedTab);
+ }
+ },
+
+ showTabDone: function(collapsedTab) {
+ collapsedTab.content.style.display = 'none';
+ this.lastExpandedTab.showExpanded();
+ if ( this.options.onShowTab )
+ this.options.onShowTab(this.lastExpandedTab);
+ },
+
+ _attachBehaviors: function() {
+ var panels = this._getDirectChildrenByTag(this.container, 'DIV');
+ for ( var i = 0 ; i < panels.length ; i++ ) {
+
+ var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
+ if ( tabChildren.length != 2 )
+ continue; // unexpected
+
+ var tabTitleBar = tabChildren[0];
+ var tabContentBox = tabChildren[1];
+ this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
+ }
+ },
+
+ _getDirectChildrenByTag: function(e, tagName) {
+ var kids = new Array();
+ var allKids = e.childNodes;
+ for( var i = 0 ; i < allKids.length ; i++ )
+ if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
+ kids.push(allKids[i]);
+ return kids;
+ }
+
+};
+
+Rico.Accordion.Tab = Class.create();
+
+Rico.Accordion.Tab.prototype = {
+
+ initialize: function(accordion, titleBar, content) {
+ this.accordion = accordion;
+ this.titleBar = titleBar;
+ this.content = content;
+ this._attachBehaviors();
+ },
+
+ collapse: function() {
+ this.showCollapsed();
+ this.content.style.height = "1px";
+ },
+
+ showCollapsed: function() {
+ this.expanded = false;
+ this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
+ this.titleBar.style.color = this.accordion.options.collapsedTextColor;
+ this.titleBar.style.fontWeight = this.accordion.options.collapsedFontWeight;
+ this.content.style.overflow = "hidden";
+ },
+
+ showExpanded: function() {
+ this.expanded = true;
+ this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
+ this.titleBar.style.color = this.accordion.options.expandedTextColor;
+ this.content.style.overflow = "auto";
+ },
+
+ titleBarClicked: function(e) {
+ if ( this.accordion.lastExpandedTab == this )
+ return;
+ this.accordion.showTab(this);
+ },
+
+ hover: function(e) {
+ this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
+ this.titleBar.style.color = this.accordion.options.hoverTextColor;
+ },
+
+ unhover: function(e) {
+ if ( this.expanded ) {
+ this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
+ this.titleBar.style.color = this.accordion.options.expandedTextColor;
+ }
+ else {
+ this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
+ this.titleBar.style.color = this.accordion.options.collapsedTextColor;
+ }
+ },
+
+ _attachBehaviors: function() {
+ this.content.style.border = "1px solid " + this.accordion.options.borderColor;
+ this.content.style.borderTopWidth = "0px";
+ this.content.style.borderBottomWidth = "0px";
+ this.content.style.margin = "0px";
+
+ this.titleBar.onclick = this.titleBarClicked.bindAsEventListener(this);
+ this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
+ this.titleBar.onmouseout = this.unhover.bindAsEventListener(this);
+ }
+
+};
+
+
+//-------------------- ricoAjaxEngine.js
+Rico.AjaxEngine = Class.create();
+
+Rico.AjaxEngine.prototype = {
+
+ initialize: function() {
+ this.ajaxElements = new Array();
+ this.ajaxObjects = new Array();
+ this.requestURLS = new Array();
+ this.options = {};
+ },
+
+ registerAjaxElement: function( anId, anElement ) {
+ if ( !anElement )
+ anElement = $(anId);
+ this.ajaxElements[anId] = anElement;
+ },
+
+ registerAjaxObject: function( anId, anObject ) {
+ this.ajaxObjects[anId] = anObject;
+ },
+
+ registerRequest: function (requestLogicalName, requestURL) {
+ this.requestURLS[requestLogicalName] = requestURL;
+ },
+
+ sendRequest: function(requestName, options) {
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 2 )
+ if (typeof arguments[1] == 'string')
+ options = {parameters: this._createQueryString(arguments, 1)};
+ this.sendRequestWithData(requestName, null, options);
+ },
+
+ sendRequestWithData: function(requestName, xmlDocument, options) {
+ var requestURL = this.requestURLS[requestName];
+ if ( requestURL == null )
+ return;
+
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 3 )
+ if (typeof arguments[2] == 'string')
+ options.parameters = this._createQueryString(arguments, 2);
+
+ new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
+ },
+
+ sendRequestAndUpdate: function(requestName,container,options) {
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 3 )
+ if (typeof arguments[2] == 'string')
+ options.parameters = this._createQueryString(arguments, 2);
+
+ this.sendRequestWithDataAndUpdate(requestName, null, container, options);
+ },
+
+ sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
+ var requestURL = this.requestURLS[requestName];
+ if ( requestURL == null )
+ return;
+
+ // Allow for backwards Compatibility
+ if ( arguments.length >= 4 )
+ if (typeof arguments[3] == 'string')
+ options.parameters = this._createQueryString(arguments, 3);
+
+ var updaterOptions = this._requestOptions(options,xmlDocument);
+
+ new Ajax.Updater(container, requestURL, updaterOptions);
+ },
+
+ // Private -- not part of intended engine API --------------------------------------------------------------------
+
+ _requestOptions: function(options,xmlDoc) {
+ var requestHeaders = ['X-Rico-Version', Rico.Version ];
+ var sendMethod = 'post';
+ if ( xmlDoc == null )
+ if (Rico.prototypeVersion < 1.4)
+ requestHeaders.push( 'Content-type', 'text/xml' );
+ else
+ sendMethod = 'get';
+ (!options) ? options = {} : '';
+
+ if (!options._RicoOptionsProcessed){
+ // Check and keep any user onComplete functions
+ if (options.onComplete)
+ options.onRicoComplete = options.onComplete;
+ // Fix onComplete
+ if (options.overrideOnComplete)
+ options.onComplete = options.overrideOnComplete;
+ else
+ options.onComplete = this._onRequestComplete.bind(this);
+ options._RicoOptionsProcessed = true;
+ }
+
+ // Set the default options and extend with any user options
+ this.options = {
+ requestHeaders: requestHeaders,
+ parameters: options.parameters,
+ postBody: xmlDoc,
+ method: sendMethod,
+ onComplete: options.onComplete
+ };
+ // Set any user options:
+ Object.extend(this.options, options);
+ return this.options;
+ },
+
+ _createQueryString: function( theArgs, offset ) {
+ var queryString = ""
+ for ( var i = offset ; i < theArgs.length ; i++ ) {
+ if ( i != offset )
+ queryString += "&";
+
+ var anArg = theArgs[i];
+
+ if ( anArg.name != undefined && anArg.value != undefined ) {
+ queryString += anArg.name + "=" + escape(anArg.value);
+ }
+ else {
+ var ePos = anArg.indexOf('=');
+ var argName = anArg.substring( 0, ePos );
+ var argValue = anArg.substring( ePos + 1 );
+ queryString += argName + "=" + escape(argValue);
+ }
+ }
+ return queryString;
+ },
+
+ _onRequestComplete : function(request) {
+ if(!request)
+ return;
+ // User can set an onFailure option - which will be called by prototype
+ if (request.status != 200)
+ return;
+
+ var response = request.responseXML.getElementsByTagName("ajax-response");
+ if (response == null || response.length != 1)
+ return;
+ this._processAjaxResponse( response[0].childNodes );
+
+ // Check if user has set a onComplete function
+ var onRicoComplete = this.options.onRicoComplete;
+ if (onRicoComplete != null)
+ onRicoComplete();
+ },
+
+ _processAjaxResponse: function( xmlResponseElements ) {
+ for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
+ var responseElement = xmlResponseElements[i];
+
+ // only process nodes of type element.....
+ if ( responseElement.nodeType != 1 )
+ continue;
+
+ var responseType = responseElement.getAttribute("type");
+ var responseId = responseElement.getAttribute("id");
+
+ if ( responseType == "object" )
+ this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
+ else if ( responseType == "element" )
+ this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
+ else
+ alert('unrecognized AjaxResponse type : ' + responseType );
+ }
+ },
+
+ _processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
+ ajaxObject.ajaxUpdate( responseElement );
+ },
+
+ _processAjaxElementUpdate: function( ajaxElement, responseElement ) {
+ ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
+ }
+
+}
+
+var ajaxEngine = new Rico.AjaxEngine();
+
+
+//-------------------- ricoColor.js
+Rico.Color = Class.create();
+
+Rico.Color.prototype = {
+
+ initialize: function(red, green, blue) {
+ this.rgb = { r: red, g : green, b : blue };
+ },
+
+ setRed: function(r) {
+ this.rgb.r = r;
+ },
+
+ setGreen: function(g) {
+ this.rgb.g = g;
+ },
+
+ setBlue: function(b) {
+ this.rgb.b = b;
+ },
+
+ setHue: function(h) {
+
+ // get an HSB model, and set the new hue...
+ var hsb = this.asHSB();
+ hsb.h = h;
+
+ // convert back to RGB...
+ this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
+ },
+
+ setSaturation: function(s) {
+ // get an HSB model, and set the new hue...
+ var hsb = this.asHSB();
+ hsb.s = s;
+
+ // convert back to RGB and set values...
+ this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
+ },
+
+ setBrightness: function(b) {
+ // get an HSB model, and set the new hue...
+ var hsb = this.asHSB();
+ hsb.b = b;
+
+ // convert back to RGB and set values...
+ this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
+ },
+
+ darken: function(percent) {
+ var hsb = this.asHSB();
+ this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
+ },
+
+ brighten: function(percent) {
+ var hsb = this.asHSB();
+ this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
+ },
+
+ blend: function(other) {
+ this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
+ this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
+ this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
+ },
+
+ isBright: function() {
+ var hsb = this.asHSB();
+ return this.asHSB().b > 0.5;
+ },
+
+ isDark: function() {
+ return ! this.isBright();
+ },
+
+ asRGB: function() {
+ return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
+ },
+
+ asHex: function() {
+ return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
+ },
+
+ asHSB: function() {
+ return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
+ },
+
+ toString: function() {
+ return this.asHex();
+ }
+
+};
+
+Rico.Color.createFromHex = function(hexCode) {
+ if(hexCode.length==4) {
+ var shortHexCode = hexCode;
+ var hexCode = '#';
+ for(var i=1;i<4;i++) hexCode += (shortHexCode.charAt(i) +
+shortHexCode.charAt(i));
+ }
+ if ( hexCode.indexOf('#') == 0 )
+ hexCode = hexCode.substring(1);
+ var red = hexCode.substring(0,2);
+ var green = hexCode.substring(2,4);
+ var blue = hexCode.substring(4,6);
+ return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
+}
+
+/**
+ * Factory method for creating a color from the background of
+ * an HTML element.
+ */
+Rico.Color.createColorFromBackground = function(elem) {
+
+ var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");
+
+ if ( actualColor == "transparent" && elem.parentNode )
+ return Rico.Color.createColorFromBackground(elem.parentNode);
+
+ if ( actualColor == null )
+ return new Rico.Color(255,255,255);
+
+ if ( actualColor.indexOf("rgb(") == 0 ) {
+ var colors = actualColor.substring(4, actualColor.length - 1 );
+ var colorArray = colors.split(",");
+ return new Rico.Color( parseInt( colorArray[0] ),
+ parseInt( colorArray[1] ),
+ parseInt( colorArray[2] ) );
+
+ }
+ else if ( actualColor.indexOf("#") == 0 ) {
+ return Rico.Color.createFromHex(actualColor);
+ }
+ else
+ return new Rico.Color(255,255,255);
+}
+
+Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
+
+ var red = 0;
+ var green = 0;
+ var blue = 0;
+
+ if (saturation == 0) {
+ red = parseInt(brightness * 255.0 + 0.5);
+ green = red;
+ blue = red;
+ }
+ else {
+ var h = (hue - Math.floor(hue)) * 6.0;
+ var f = h - Math.floor(h);
+ var p = brightness * (1.0 - saturation);
+ var q = brightness * (1.0 - saturation * f);
+ var t = brightness * (1.0 - (saturation * (1.0 - f)));
+
+ switch (parseInt(h)) {
+ case 0:
+ red = (brightness * 255.0 + 0.5);
+ green = (t * 255.0 + 0.5);
+ blue = (p * 255.0 + 0.5);
+ break;
+ case 1:
+ red = (q * 255.0 + 0.5);
+ green = (brightness * 255.0 + 0.5);
+ blue = (p * 255.0 + 0.5);
+ break;
+ case 2:
+ red = (p * 255.0 + 0.5);
+ green = (brightness * 255.0 + 0.5);
+ blue = (t * 255.0 + 0.5);
+ break;
+ case 3:
+ red = (p * 255.0 + 0.5);
+ green = (q * 255.0 + 0.5);
+ blue = (brightness * 255.0 + 0.5);
+ break;
+ case 4:
+ red = (t * 255.0 + 0.5);
+ green = (p * 255.0 + 0.5);
+ blue = (brightness * 255.0 + 0.5);
+ break;
+ case 5:
+ red = (brightness * 255.0 + 0.5);
+ green = (p * 255.0 + 0.5);
+ blue = (q * 255.0 + 0.5);
+ break;
+ }
+ }
+
+ return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
+}
+
+Rico.Color.RGBtoHSB = function(r, g, b) {
+
+ var hue;
+ var saturation;
+ var brightness;
+
+ var cmax = (r > g) ? r : g;
+ if (b > cmax)
+ cmax = b;
+
+ var cmin = (r < g) ? r : g;
+ if (b < cmin)
+ cmin = b;
+
+ brightness = cmax / 255.0;
+ if (cmax != 0)
+ saturation = (cmax - cmin)/cmax;
+ else
+ saturation = 0;
+
+ if (saturation == 0)
+ hue = 0;
+ else {
+ var redc = (cmax - r)/(cmax - cmin);
+ var greenc = (cmax - g)/(cmax - cmin);
+ var bluec = (cmax - b)/(cmax - cmin);
+
+ if (r == cmax)
+ hue = bluec - greenc;
+ else if (g == cmax)
+ hue = 2.0 + redc - bluec;
+ else
+ hue = 4.0 + greenc - redc;
+
+ hue = hue / 6.0;
+ if (hue < 0)
+ hue = hue + 1.0;
+ }
+
+ return { h : hue, s : saturation, b : brightness };
+}
+
+
+//-------------------- ricoCorner.js
+Rico.Corner = {
+
+ round: function(e, options) {
+ var e = $(e);
+ this._setOptions(options);
+
+ var color = this.options.color;
+ if ( this.options.color == "fromElement" )
+ color = this._background(e);
+
+ var bgColor = this.options.bgColor;
+ if ( this.options.bgColor == "fromParent" )
+ bgColor = this._background(e.offsetParent);
+
+ this._roundCornersImpl(e, color, bgColor);
+ },
+
+ _roundCornersImpl: function(e, color, bgColor) {
+ if(this.options.border)
+ this._renderBorder(e,bgColor);
+ if(this._isTopRounded())
+ this._roundTopCorners(e,color,bgColor);
+ if(this._isBottomRounded())
+ this._roundBottomCorners(e,color,bgColor);
+ },
+
+ _renderBorder: function(el,bgColor) {
+ var borderValue = "1px solid " + this._borderColor(bgColor);
+ var borderL = "border-left: " + borderValue;
+ var borderR = "border-right: " + borderValue;
+ var style = "style='" + borderL + ";" + borderR + "'";
+ el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
+ },
+
+ _roundTopCorners: function(el, color, bgColor) {
+ var corner = this._createCorner(bgColor);
+ for(var i=0 ; i < this.options.numSlices ; i++ )
+ corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
+ el.style.paddingTop = 0;
+ el.insertBefore(corner,el.firstChild);
+ },
+
+ _roundBottomCorners: function(el, color, bgColor) {
+ var corner = this._createCorner(bgColor);
+ for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
+ corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
+ el.style.paddingBottom = 0;
+ el.appendChild(corner);
+ },
+
+ _createCorner: function(bgColor) {
+ var corner = document.createElement("div");
+ corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
+ return corner;
+ },
+
+ _createCornerSlice: function(color,bgColor, n, position) {
+ var slice = document.createElement("span");
+
+ var inStyle = slice.style;
+ inStyle.backgroundColor = color;
+ inStyle.display = "block";
+ inStyle.height = "1px";
+ inStyle.overflow = "hidden";
+ inStyle.fontSize = "1px";
+
+ var borderColor = this._borderColor(color,bgColor);
+ if ( this.options.border && n == 0 ) {
+ inStyle.borderTopStyle = "solid";
+ inStyle.borderTopWidth = "1px";
+ inStyle.borderLeftWidth = "0px";
+ inStyle.borderRightWidth = "0px";
+ inStyle.borderBottomWidth = "0px";
+ inStyle.height = "0px"; // assumes css compliant box model
+ inStyle.borderColor = borderColor;
+ }
+ else if(borderColor) {
+ inStyle.borderColor = borderColor;
+ inStyle.borderStyle = "solid";
+ inStyle.borderWidth = "0px 1px";
+ }
+
+ if ( !this.options.compact && (n == (this.options.numSlices-1)) )
+ inStyle.height = "2px";
+
+ this._setMargin(slice, n, position);
+ this._setBorder(slice, n, position);
+ return slice;
+ },
+
+ _setOptions: function(options) {
+ this.options = {
+ corners : "all",
+ color : "fromElement",
+ bgColor : "fromParent",
+ blend : true,
+ border : false,
+ compact : false
+ }
+ Object.extend(this.options, options || {});
+
+ this.options.numSlices = this.options.compact ? 2 : 4;
+ if ( this._isTransparent() )
+ this.options.blend = false;
+ },
+
+ _whichSideTop: function() {
+ if ( this._hasString(this.options.corners, "all", "top") )
+ return "";
+
+ if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
+ return "";
+
+ if (this.options.corners.indexOf("tl") >= 0)
+ return "left";
+ else if (this.options.corners.indexOf("tr") >= 0)
+ return "right";
+ return "";
+ },
+
+ _whichSideBottom: function() {
+ if ( this._hasString(this.options.corners, "all", "bottom") )
+ return "";
+
+ if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
+ return "";
+
+ if(this.options.corners.indexOf("bl") >=0)
+ return "left";
+ else if(this.options.corners.indexOf("br")>=0)
+ return "right";
+ return "";
+ },
+
+ _borderColor : function(color,bgColor) {
+ if ( color == "transparent" )
+ return bgColor;
+ else if ( this.options.border )
+ return this.options.border;
+ else if ( this.options.blend )
+ return this._blend( bgColor, color );
+ else
+ return "";
+ },
+
+
+ _setMargin: function(el, n, corners) {
+ var marginSize = this._marginSize(n);
+ var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
+
+ if ( whichSide == "left" ) {
+ el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
+ }
+ else if ( whichSide == "right" ) {
+ el.style.marginRight = marginSize + "px"; el.style.marginLeft = "0px";
+ }
+ else {
+ el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
+ }
+ },
+
+ _setBorder: function(el,n,corners) {
+ var borderSize = this._borderSize(n);
+ var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
+ if ( whichSide == "left" ) {
+ el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
+ }
+ else if ( whichSide == "right" ) {
+ el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth = "0px";
+ }
+ else {
+ el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
+ }
+ if (this.options.border != false)
+ el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
+ },
+
+ _marginSize: function(n) {
+ if ( this._isTransparent() )
+ return 0;
+
+ var marginSizes = [ 5, 3, 2, 1 ];
+ var blendedMarginSizes = [ 3, 2, 1, 0 ];
+ var compactMarginSizes = [ 2, 1 ];
+ var smBlendedMarginSizes = [ 1, 0 ];
+
+ if ( this.options.compact && this.options.blend )
+ return smBlendedMarginSizes[n];
+ else if ( this.options.compact )
+ return compactMarginSizes[n];
+ else if ( this.options.blend )
+ return blendedMarginSizes[n];
+ else
+ return marginSizes[n];
+ },
+
+ _borderSize: function(n) {
+ var transparentBorderSizes = [ 5, 3, 2, 1 ];
+ var blendedBorderSizes = [ 2, 1, 1, 1 ];
+ var compactBorderSizes = [ 1, 0 ];
+ var actualBorderSizes = [ 0, 2, 0, 0 ];
+
+ if ( this.options.compact && (this.options.blend || this._isTransparent()) )
+ return 1;
+ else if ( this.options.compact )
+ return compactBorderSizes[n];
+ else if ( this.options.blend )
+ return blendedBorderSizes[n];
+ else if ( this.options.border )
+ return actualBorderSizes[n];
+ else if ( this._isTransparent() )
+ return transparentBorderSizes[n];
+ return 0;
+ },
+
+ _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
+ _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
+ _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
+ _isTransparent: function() { return this.options.color == "transparent"; },
+ _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
+ _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
+ _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
+}
+
+
+//-------------------- ricoDragAndDrop.js
+Rico.DragAndDrop = Class.create();
+
+Rico.DragAndDrop.prototype = {
+
+ initialize: function() {
+ this.dropZones = new Array();
+ this.draggables = new Array();
+ this.currentDragObjects = new Array();
+ this.dragElement = null;
+ this.lastSelectedDraggable = null;
+ this.currentDragObjectVisible = false;
+ this.interestedInMotionEvents = false;
+ this._mouseDown = this._mouseDownHandler.bindAsEventListener(this);
+ this._mouseMove = this._mouseMoveHandler.bindAsEventListener(this);
+ this._mouseUp = this._mouseUpHandler.bindAsEventListener(this);
+ },
+
+ registerDropZone: function(aDropZone) {
+ this.dropZones[ this.dropZones.length ] = aDropZone;
+ },
+
+ deregisterDropZone: function(aDropZone) {
+ var newDropZones = new Array();
+ var j = 0;
+ for ( var i = 0 ; i < this.dropZones.length ; i++ ) {
+ if ( this.dropZones[i] != aDropZone )
+ newDropZones[j++] = this.dropZones[i];
+ }
+
+ this.dropZones = newDropZones;
+ },
+
+ clearDropZones: function() {
+ this.dropZones = new Array();
+ },
+
+ registerDraggable: function( aDraggable ) {
+ this.draggables[ this.draggables.length ] = aDraggable;
+ this._addMouseDownHandler( aDraggable );
+ },
+
+ clearSelection: function() {
+ for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+ this.currentDragObjects[i].deselect();
+ this.currentDragObjects = new Array();
+ this.lastSelectedDraggable = null;
+ },
+
+ hasSelection: function() {
+ return this.currentDragObjects.length > 0;
+ },
+
+ setStartDragFromElement: function( e, mouseDownElement ) {
+ this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
+ this.startx = e.screenX - this.origPos.x
+ this.starty = e.screenY - this.origPos.y
+ //this.startComponentX = e.layerX ? e.layerX : e.offsetX;
+ //this.startComponentY = e.layerY ? e.layerY : e.offsetY;
+ //this.adjustedForDraggableSize = false;
+
+ this.interestedInMotionEvents = this.hasSelection();
+ this._terminateEvent(e);
+ },
+
+ updateSelection: function( draggable, extendSelection ) {
+ if ( ! extendSelection )
+ this.clearSelection();
+
+ if ( draggable.isSelected() ) {
+ this.currentDragObjects.removeItem(draggable);
+ draggable.deselect();
+ if ( draggable == this.lastSelectedDraggable )
+ this.lastSelectedDraggable = null;
+ }
+ else {
+ this.currentDragObjects[ this.currentDragObjects.length ] = draggable;
+ draggable.select();
+ this.lastSelectedDraggable = draggable;
+ }
+ },
+
+ _mouseDownHandler: function(e) {
+ if ( arguments.length == 0 )
+ e = event;
+
+ // if not button 1 ignore it...
+ var nsEvent = e.which != undefined;
+ if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
+ return;
+
+ var eventTarget = e.target ? e.target : e.srcElement;
+ var draggableObject = eventTarget.draggable;
+
+ var candidate = eventTarget;
+ while (draggableObject == null && candidate.parentNode) {
+ candidate = candidate.parentNode;
+ draggableObject = candidate.draggable;
+ }
+
+ if ( draggableObject == null )
+ return;
+
+ this.updateSelection( draggableObject, e.ctrlKey );
+
+ // clear the drop zones postion cache...
+ if ( this.hasSelection() )
+ for ( var i = 0 ; i < this.dropZones.length ; i++ )
+ this.dropZones[i].clearPositionCache();
+
+ this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() );
+ },
+
+
+ _mouseMoveHandler: function(e) {
+ var nsEvent = e.which != undefined;
+ if ( !this.interestedInMotionEvents ) {
+ //this._terminateEvent(e);
+ return;
+ }
+
+ if ( ! this.hasSelection() )
+ return;
+
+ if ( ! this.currentDragObjectVisible )
+ this._startDrag(e);
+
+ if ( !this.activatedDropZones )
+ this._activateRegisteredDropZones();
+
+ //if ( !this.adjustedForDraggableSize )
+ // this._adjustForDraggableSize(e);
+
+ this._updateDraggableLocation(e);
+ this._updateDropZonesHover(e);
+
+ this._terminateEvent(e);
+ },
+
+ _makeDraggableObjectVisible: function(e)
+ {
+ if ( !this.hasSelection() )
+ return;
+
+ var dragElement;
+ if ( this.currentDragObjects.length > 1 )
+ dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects);
+ else
+ dragElement = this.currentDragObjects[0].getSingleObjectDragGUI();
+
+ // go ahead and absolute position it...
+ if ( RicoUtil.getElementsComputedStyle(dragElement, "position") != "absolute" )
+ dragElement.style.position = "absolute";
+
+ // need to parent him into the document...
+ if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 )
+ document.body.appendChild(dragElement);
+
+ this.dragElement = dragElement;
+ this._updateDraggableLocation(e);
+
+ this.currentDragObjectVisible = true;
+ },
+
+ /**
+ _adjustForDraggableSize: function(e) {
+ var dragElementWidth = this.dragElement.offsetWidth;
+ var dragElementHeight = this.dragElement.offsetHeight;
+ if ( this.startComponentX > dragElementWidth )
+ this.startx -= this.startComponentX - dragElementWidth + 2;
+ if ( e.offsetY ) {
+ if ( this.startComponentY > dragElementHeight )
+ this.starty -= this.startComponentY - dragElementHeight + 2;
+ }
+ this.adjustedForDraggableSize = true;
+ },
+ **/
+
+ _leftOffset: function(e) {
+ return e.offsetX ? document.body.scrollLeft : 0
+ },
+
+ _topOffset: function(e) {
+ return e.offsetY ? document.body.scrollTop:0
+ },
+
+
+ _updateDraggableLocation: function(e) {
+ var dragObjectStyle = this.dragElement.style;
+ dragObjectStyle.left = (e.screenX + this._leftOffset(e) - this.startx) + "px"
+ dragObjectStyle.top = (e.screenY + this._topOffset(e) - this.starty) + "px";
+ },
+
+ _updateDropZonesHover: function(e) {
+ var n = this.dropZones.length;
+ for ( var i = 0 ; i < n ; i++ ) {
+ if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) )
+ this.dropZones[i].hideHover();
+ }
+
+ for ( var i = 0 ; i < n ; i++ ) {
+ if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
+ if ( this.dropZones[i].canAccept(this.currentDragObjects) )
+ this.dropZones[i].showHover();
+ }
+ }
+ },
+
+ _startDrag: function(e) {
+ for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+ this.currentDragObjects[i].startDrag();
+
+ this._makeDraggableObjectVisible(e);
+ },
+
+ _mouseUpHandler: function(e) {
+ if ( ! this.hasSelection() )
+ return;
+
+ var nsEvent = e.which != undefined;
+ if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
+ return;
+
+ this.interestedInMotionEvents = false;
+
+ if ( this.dragElement == null ) {
+ this._terminateEvent(e);
+ return;
+ }
+
+ if ( this._placeDraggableInDropZone(e) )
+ this._completeDropOperation(e);
+ else {
+ this._terminateEvent(e);
+ new Rico.Effect.Position( this.dragElement,
+ this.origPos.x,
+ this.origPos.y,
+ 200,
+ 20,
+ { complete : this._doCancelDragProcessing.bind(this) } );
+ }
+
+ Event.stopObserving(document.body, "mousemove", this._mouseMove);
+ Event.stopObserving(document.body, "mouseup", this._mouseUp);
+ },
+
+ _retTrue: function () {
+ return true;
+ },
+
+ _completeDropOperation: function(e) {
+ if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
+ if ( this.dragElement.parentNode != null )
+ this.dragElement.parentNode.removeChild(this.dragElement);
+ }
+
+ this._deactivateRegisteredDropZones();
+ this._endDrag();
+ this.clearSelection();
+ this.dragElement = null;
+ this.currentDragObjectVisible = false;
+ this._terminateEvent(e);
+ },
+
+ _doCancelDragProcessing: function() {
+ this._cancelDrag();
+
+ if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement)
+ if ( this.dragElement.parentNode != null )
+ this.dragElement.parentNode.removeChild(this.dragElement);
+
+
+ this._deactivateRegisteredDropZones();
+ this.dragElement = null;
+ this.currentDragObjectVisible = false;
+ },
+
+ _placeDraggableInDropZone: function(e) {
+ var foundDropZone = false;
+ var n = this.dropZones.length;
+ for ( var i = 0 ; i < n ; i++ ) {
+ if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
+ if ( this.dropZones[i].canAccept(this.currentDragObjects) ) {
+ this.dropZones[i].hideHover();
+ this.dropZones[i].accept(this.currentDragObjects);
+ foundDropZone = true;
+ break;
+ }
+ }
+ }
+
+ return foundDropZone;
+ },
+
+ _cancelDrag: function() {
+ for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+ this.currentDragObjects[i].cancelDrag();
+ },
+
+ _endDrag: function() {
+ for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
+ this.currentDragObjects[i].endDrag();
+ },
+
+ _mousePointInDropZone: function( e, dropZone ) {
+
+ var absoluteRect = dropZone.getAbsoluteRect();
+
+ return e.clientX > absoluteRect.left + this._leftOffset(e) &&
+ e.clientX < absoluteRect.right + this._leftOffset(e) &&
+ e.clientY > absoluteRect.top + this._topOffset(e) &&
+ e.clientY < absoluteRect.bottom + this._topOffset(e);
+ },
+
+ _addMouseDownHandler: function( aDraggable )
+ {
+ htmlElement = aDraggable.getMouseDownHTMLElement();
+ if ( htmlElement != null ) {
+ htmlElement.draggable = aDraggable;
+ Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this));
+ Event.observe(htmlElement, "mousedown", this._mouseDown);
+ }
+ },
+
+ _activateRegisteredDropZones: function() {
+ var n = this.dropZones.length;
+ for ( var i = 0 ; i < n ; i++ ) {
+ var dropZone = this.dropZones[i];
+ if ( dropZone.canAccept(this.currentDragObjects) )
+ dropZone.activate();
+ }
+
+ this.activatedDropZones = true;
+ },
+
+ _deactivateRegisteredDropZones: function() {
+ var n = this.dropZones.length;
+ for ( var i = 0 ; i < n ; i++ )
+ this.dropZones[i].deactivate();
+ this.activatedDropZones = false;
+ },
+
+ _onmousedown: function () {
+ Event.observe(document.body, "mousemove", this._mouseMove);
+ Event.observe(document.body, "mouseup", this._mouseUp);
+ },
+
+ _terminateEvent: function(e) {
+ if ( e.stopPropagation != undefined )
+ e.stopPropagation();
+ else if ( e.cancelBubble != undefined )
+ e.cancelBubble = true;
+
+ if ( e.preventDefault != undefined )
+ e.preventDefault();
+ else
+ e.returnValue = false;
+ },
+
+
+ initializeEventHandlers: function() {
+ if ( typeof document.implementation != "undefined" &&
+ document.implementation.hasFeature("HTML", "1.0") &&
+ document.implementation.hasFeature("Events", "2.0") &&
+ document.implementation.hasFeature("CSS", "2.0") ) {
+ document.addEventListener("mouseup", this._mouseUpHandler.bindAsEventListener(this), false);
+ document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false);
+ }
+ else {
+ document.attachEvent( "onmouseup", this._mouseUpHandler.bindAsEventListener(this) );
+ document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) );
+ }
+ }
+ }
+
+ var dndMgr = new Rico.DragAndDrop();
+ dndMgr.initializeEventHandlers();
+
+
+//-------------------- ricoDraggable.js
+Rico.Draggable = Class.create();
+
+Rico.Draggable.prototype = {
+
+ initialize: function( type, htmlElement ) {
+ this.type = type;
+ this.htmlElement = $(htmlElement);
+ this.selected = false;
+ },
+
+ /**
+ * Returns the HTML element that should have a mouse down event
+ * added to it in order to initiate a drag operation
+ *
+ **/
+ getMouseDownHTMLElement: function() {
+ return this.htmlElement;
+ },
+
+ select: function() {
+ this.selected = true;
+
+ if ( this.showingSelected )
+ return;
+
+ var htmlElement = this.getMouseDownHTMLElement();
+
+ var color = Rico.Color.createColorFromBackground(htmlElement);
+ color.isBright() ? color.darken(0.033) : color.brighten(0.033);
+
+ this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color");
+ htmlElement.style.backgroundColor = color.asHex();
+ this.showingSelected = true;
+ },
+
+ deselect: function() {
+ this.selected = false;
+ if ( !this.showingSelected )
+ return;
+
+ var htmlElement = this.getMouseDownHTMLElement();
+
+ htmlElement.style.backgroundColor = this.saveBackground;
+ this.showingSelected = false;
+ },
+
+ isSelected: function() {
+ return this.selected;
+ },
+
+ startDrag: function() {
+ },
+
+ cancelDrag: function() {
+ },
+
+ endDrag: function() {
+ },
+
+ getSingleObjectDragGUI: function() {
+ return this.htmlElement;
+ },
+
+ getMultiObjectDragGUI: function( draggables ) {
+ return this.htmlElement;
+ },
+
+ getDroppedGUI: function() {
+ return this.htmlElement;
+ },
+
+ toString: function() {
+ return this.type + ":" + this.htmlElement + ":";
+ }
+
+}
+
+
+//-------------------- ricoDropzone.js
+Rico.Dropzone = Class.create();
+
+Rico.Dropzone.prototype = {
+
+ initialize: function( htmlElement ) {
+ this.htmlElement = $(htmlElement);
+ this.absoluteRect = null;
+ },
+
+ getHTMLElement: function() {
+ return this.htmlElement;
+ },
+
+ clearPositionCache: function() {
+ this.absoluteRect = null;
+ },
+
+ getAbsoluteRect: function() {
+ if ( this.absoluteRect == null ) {
+ var htmlElement = this.getHTMLElement();
+ var pos = RicoUtil.toViewportPosition(htmlElement);
+
+ this.absoluteRect = {
+ top: pos.y,
+ left: pos.x,
+ bottom: pos.y + htmlElement.offsetHeight,
+ right: pos.x + htmlElement.offsetWidth
+ };
+ }
+ return this.absoluteRect;
+ },
+
+ activate: function() {
+ var htmlElement = this.getHTMLElement();
+ if (htmlElement == null || this.showingActive)
+ return;
+
+ this.showingActive = true;
+ this.saveBackgroundColor = htmlElement.style.backgroundColor;
+
+ var fallbackColor = "#ffea84";
+ var currentColor = Rico.Color.createColorFromBackground(htmlElement);
+ if ( currentColor == null )
+ htmlElement.style.backgroundColor = fallbackColor;
+ else {
+ currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2);
+ htmlElement.style.backgroundColor = currentColor.asHex();
+ }
+ },
+
+ deactivate: function() {
+ var htmlElement = this.getHTMLElement();
+ if (htmlElement == null || !this.showingActive)
+ return;
+
+ htmlElement.style.backgroundColor = this.saveBackgroundColor;
+ this.showingActive = false;
+ this.saveBackgroundColor = null;
+ },
+
+ showHover: function() {
+ var htmlElement = this.getHTMLElement();
+ if ( htmlElement == null || this.showingHover )
+ return;
+
+ this.saveBorderWidth = htmlElement.style.borderWidth;
+ this.saveBorderStyle = htmlElement.style.borderStyle;
+ this.saveBorderColor = htmlElement.style.borderColor;
+
+ this.showingHover = true;
+ htmlElement.style.borderWidth = "1px";
+ htmlElement.style.borderStyle = "solid";
+ //htmlElement.style.borderColor = "#ff9900";
+ htmlElement.style.borderColor = "#ffff00";
+ },
+
+ hideHover: function() {
+ var htmlElement = this.getHTMLElement();
+ if ( htmlElement == null || !this.showingHover )
+ return;
+
+ htmlElement.style.borderWidth = this.saveBorderWidth;
+ htmlElement.style.borderStyle = this.saveBorderStyle;
+ htmlElement.style.borderColor = this.saveBorderColor;
+ this.showingHover = false;
+ },
+
+ canAccept: function(draggableObjects) {
+ return true;
+ },
+
+ accept: function(draggableObjects) {
+ var htmlElement = this.getHTMLElement();
+ if ( htmlElement == null )
+ return;
+
+ n = draggableObjects.length;
+ for ( var i = 0 ; i < n ; i++ )
+ {
+ var theGUI = draggableObjects[i].getDroppedGUI();
+ if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
+ {
+ theGUI.style.position = "static";
+ theGUI.style.top = "";
+ theGUI.style.top = "";
+ }
+ htmlElement.appendChild(theGUI);
+ }
+ }
+}
+
+
+//-------------------- ricoEffects.js
+
+Rico.Effect = {};
+
+Rico.Effect.SizeAndPosition = Class.create();
+Rico.Effect.SizeAndPosition.prototype = {
+
+ initialize: function(element, x, y, w, h, duration, steps, options) {
+ this.element = $(element);
+ this.x = x;
+ this.y = y;
+ this.w = w;
+ this.h = h;
+ this.duration = duration;
+ this.steps = steps;
+ this.options = arguments[7] || {};
+
+ this.sizeAndPosition();
+ },
+
+ sizeAndPosition: function() {
+ if (this.isFinished()) {
+ if(this.options.complete) this.options.complete(this);
+ return;
+ }
+
+ if (this.timer)
+ clearTimeout(this.timer);
+
+ var stepDuration = Math.round(this.duration/this.steps) ;
+
+ // Get original values: x,y = top left corner; w,h = width height
+ var currentX = this.element.offsetLeft;
+ var currentY = this.element.offsetTop;
+ var currentW = this.element.offsetWidth;
+ var currentH = this.element.offsetHeight;
+
+ // If values not set, or zero, we do not modify them, and take original as final as well
+ this.x = (this.x) ? this.x : currentX;
+ this.y = (this.y) ? this.y : currentY;
+ this.w = (this.w) ? this.w : currentW;
+ this.h = (this.h) ? this.h : currentH;
+
+ // how much do we need to modify our values for each step?
+ var difX = this.steps > 0 ? (this.x - currentX)/this.steps : 0;
+ var difY = this.steps > 0 ? (this.y - currentY)/this.steps : 0;
+ var difW = this.steps > 0 ? (this.w - currentW)/this.steps : 0;
+ var difH = this.steps > 0 ? (this.h - currentH)/this.steps : 0;
+
+ this.moveBy(difX, difY);
+ this.resizeBy(difW, difH);
+
+ this.duration -= stepDuration;
+ this.steps--;
+
+ this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
+ },
+
+ isFinished: function() {
+ return this.steps <= 0;
+ },
+
+ moveBy: function( difX, difY ) {
+ var currentLeft = this.element.offsetLeft;
+ var currentTop = this.element.offsetTop;
+ var intDifX = parseInt(difX);
+ var intDifY = parseInt(difY);
+
+ var style = this.element.style;
+ if ( intDifX != 0 )
+ style.left = (currentLeft + intDifX) + "px";
+ if ( intDifY != 0 )
+ style.top = (currentTop + intDifY) + "px";
+ },
+
+ resizeBy: function( difW, difH ) {
+ var currentWidth = this.element.offsetWidth;
+ var currentHeight = this.element.offsetHeight;
+ var intDifW = parseInt(difW);
+ var intDifH = parseInt(difH);
+
+ var style = this.element.style;
+ if ( intDifW != 0 )
+ style.width = (currentWidth + intDifW) + "px";
+ if ( intDifH != 0 )
+ style.height = (currentHeight + intDifH) + "px";
+ }
+}
+
+Rico.Effect.Size = Class.create();
+Rico.Effect.Size.prototype = {
+
+ initialize: function(element, w, h, duration, steps, options) {
+ new Rico.Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
+ }
+}
+
+Rico.Effect.Position = Class.create();
+Rico.Effect.Position.prototype = {
+
+ initialize: function(element, x, y, duration, steps, options) {
+ new Rico.Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
+ }
+}
+
+Rico.Effect.Round = Class.create();
+Rico.Effect.Round.prototype = {
+
+ initialize: function(tagName, className, options) {
+ var elements = document.getElementsByTagAndClassName(tagName,className);
+ for ( var i = 0 ; i < elements.length ; i++ )
+ Rico.Corner.round( elements[i], options );
+ }
+};
+
+Rico.Effect.FadeTo = Class.create();
+Rico.Effect.FadeTo.prototype = {
+
+ initialize: function( element, opacity, duration, steps, options) {
+ this.element = $(element);
+ this.opacity = opacity;
+ this.duration = duration;
+ this.steps = steps;
+ this.options = arguments[4] || {};
+ this.fadeTo();
+ },
+
+ fadeTo: function() {
+ if (this.isFinished()) {
+ if(this.options.complete) this.options.complete(this);
+ return;
+ }
+
+ if (this.timer)
+ clearTimeout(this.timer);
+
+ var stepDuration = Math.round(this.duration/this.steps) ;
+ var currentOpacity = this.getElementOpacity();
+ var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;
+
+ this.changeOpacityBy(delta);
+ this.duration -= stepDuration;
+ this.steps--;
+
+ this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
+ },
+
+ changeOpacityBy: function(v) {
+ var currentOpacity = this.getElementOpacity();
+ var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
+ this.element.ricoOpacity = newOpacity;
+
+ this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
+ this.element.style.opacity = newOpacity; /*//*/;
+ },
+
+ isFinished: function() {
+ return this.steps <= 0;
+ },
+
+ getElementOpacity: function() {
+ if ( this.element.ricoOpacity == undefined ) {
+ var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
+ this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
+ }
+ return parseFloat(this.element.ricoOpacity);
+ }
+}
+
+Rico.Effect.AccordionSize = Class.create();
+
+Rico.Effect.AccordionSize.prototype = {
+
+ initialize: function(e1, e2, start, end, duration, steps, options) {
+ this.e1 = $(e1);
+ this.e2 = $(e2);
+ this.start = start;
+ this.end = end;
+ this.duration = duration;
+ this.steps = steps;
+ this.options = arguments[6] || {};
+
+ this.accordionSize();
+ },
+
+ accordionSize: function() {
+
+ if (this.isFinished()) {
+ // just in case there are round errors or such...
+ this.e1.style.height = this.start + "px";
+ this.e2.style.height = this.end + "px";
+
+ if(this.options.complete)
+ this.options.complete(this);
+ return;
+ }
+
+ if (this.timer)
+ clearTimeout(this.timer);
+
+ var stepDuration = Math.round(this.duration/this.steps) ;
+
+ var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
+ this.resizeBy(diff);
+
+ this.duration -= stepDuration;
+ this.steps--;
+
+ this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
+ },
+
+ isFinished: function() {
+ return this.steps <= 0;
+ },
+
+ resizeBy: function(diff) {
+ var h1Height = this.e1.offsetHeight;
+ var h2Height = this.e2.offsetHeight;
+ var intDiff = parseInt(diff);
+ if ( diff != 0 ) {
+ this.e1.style.height = (h1Height - intDiff) + "px";
+ this.e2.style.height = (h2Height + intDiff) + "px";
+ }
+ }
+
+};
+
+
+//-------------------- ricoLiveGrid.js
+// Rico.LiveGridMetaData -----------------------------------------------------
+
+Rico.LiveGridMetaData = Class.create();
+
+Rico.LiveGridMetaData.prototype = {
+
+ initialize: function( pageSize, totalRows, columnCount, options ) {
+ this.pageSize = pageSize;
+ this.totalRows = totalRows;
+ this.setOptions(options);
+ this.ArrowHeight = 16;
+ this.columnCount = columnCount;
+ },
+
+ setOptions: function(options) {
+ this.options = {
+ largeBufferSize : 7.0, // 7 pages
+ nearLimitFactor : 0.2 // 20% of buffer
+ };
+ Object.extend(this.options, options || {});
+ },
+
+ getPageSize: function() {
+ return this.pageSize;
+ },
+
+ getTotalRows: function() {
+ return this.totalRows;
+ },
+
+ setTotalRows: function(n) {
+ this.totalRows = n;
+ },
+
+ getLargeBufferSize: function() {
+ return parseInt(this.options.largeBufferSize * this.pageSize);
+ },
+
+ getLimitTolerance: function() {
+ return parseInt(this.getLargeBufferSize() * this.options.nearLimitFactor);
+ }
+};
+
+// Rico.LiveGridScroller -----------------------------------------------------
+
+Rico.LiveGridScroller = Class.create();
+
+Rico.LiveGridScroller.prototype = {
+
+ initialize: function(liveGrid, viewPort) {
+ this.isIE = navigator.userAgent.toLowerCase().indexOf("msie") >= 0;
+ this.liveGrid = liveGrid;
+ this.metaData = liveGrid.metaData;
+ this.createScrollBar();
+ this.scrollTimeout = null;
+ this.lastScrollPos = 0;
+ this.viewPort = viewPort;
+ this.rows = new Array();
+ },
+
+ isUnPlugged: function() {
+ return this.scrollerDiv.onscroll == null;
+ },
+
+ plugin: function() {
+ this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
+ },
+
+ unplug: function() {
+ this.scrollerDiv.onscroll = null;
+ },
+
+ sizeIEHeaderHack: function() {
+ if ( !this.isIE ) return;
+ var headerTable = $(this.liveGrid.tableId + "_header");
+ if ( headerTable )
+ headerTable.rows[0].cells[0].style.width =
+ (headerTable.rows[0].cells[0].offsetWidth + 1) + "px";
+ },
+
+ createScrollBar: function() {
+ var visibleHeight = this.liveGrid.viewPort.visibleHeight();
+ // create the outer div...
+ this.scrollerDiv = document.createElement("div");
+ var scrollerStyle = this.scrollerDiv.style;
+ this.scrollerDiv.id = "sc"
+ scrollerStyle.borderRight = this.liveGrid.options.scrollerBorderRight;
+ scrollerStyle.position = "relative";
+ scrollerStyle.left = this.isIE ? "-6px" : "-3px";
+ scrollerStyle.width = "19px";
+ scrollerStyle.height = visibleHeight + "px";
+ scrollerStyle.overflow = "auto";
+
+ // create the inner div...
+ this.heightDiv = document.createElement("div");
+ this.heightDiv.style.width = "1px";
+
+ this.heightDiv.style.height = parseInt(visibleHeight *
+ this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px" ;
+ this.scrollerDiv.appendChild(this.heightDiv);
+ this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);
+
+ var table = this.liveGrid.table;
+ table.parentNode.parentNode.insertBefore( this.scrollerDiv, table.parentNode.nextSibling );
+ var eventName = this.isIE ? "mousewheel" : "DOMMouseScroll";
+ Event.observe(table, eventName,
+ function(evt) {
+ if (evt.wheelDelta>=0 || evt.detail < 0) //wheel-up
+ this.scrollerDiv.scrollTop -= (2*this.viewPort.rowHeight);
+ else
+ this.scrollerDiv.scrollTop += (2*this.viewPort.rowHeight);
+ this.handleScroll(false);
+ }.bindAsEventListener(this),
+ false);
+ },
+
+ updateSize: function() {
+ var table = this.liveGrid.table;
+ var visibleHeight = this.viewPort.visibleHeight();
+ this.heightDiv.style.height = parseInt(visibleHeight *
+ this.metaData.getTotalRows()/this.metaData.getPageSize()) + "px";
+ },
+
+ rowToPixel: function(rowOffset) {
+ return (rowOffset / this.metaData.getTotalRows()) * this.heightDiv.offsetHeight
+ },
+
+ moveScroll: function(rowOffset) {
+ this.scrollerDiv.scrollTop = this.rowToPixel(rowOffset);
+ if ( this.metaData.options.onscroll )
+ this.metaData.options.onscroll( this.liveGrid, rowOffset );
+ },
+
+ handleScroll: function() {
+ if ( this.scrollTimeout )
+ clearTimeout( this.scrollTimeout );
+
+ var scrollDiff = this.lastScrollPos-this.scrollerDiv.scrollTop;
+ if (scrollDiff != 0.00) {
+ var r = this.scrollerDiv.scrollTop % this.viewPort.rowHeight;
+ if (r != 0) {
+ this.unplug();
+ if ( scrollDiff < 0 ) {
+ this.scrollerDiv.scrollTop += (this.viewPort.rowHeight-r);
+ } else {
+ this.scrollerDiv.scrollTop -= r;
+ }
+ this.plugin();
+ }
+ }
+ var contentOffset = parseInt(this.scrollerDiv.scrollTop / this.viewPort.rowHeight);
+ this.liveGrid.requestContentRefresh(contentOffset);
+ this.viewPort.scrollTo(this.scrollerDiv.scrollTop);
+
+ if ( this.metaData.options.onscroll )
+ this.metaData.options.onscroll( this.liveGrid, contentOffset );
+
+ this.scrollTimeout = setTimeout(this.scrollIdle.bind(this), 1200 );
+ this.lastScrollPos = this.scrollerDiv.scrollTop;
+
+ },
+
+ scrollIdle: function() {
+ if ( this.metaData.options.onscrollidle )
+ this.metaData.options.onscrollidle();
+ }
+};
+
+// Rico.LiveGridBuffer -----------------------------------------------------
+
+Rico.LiveGridBuffer = Class.create();
+
+Rico.LiveGridBuffer.prototype = {
+
+ initialize: function(metaData, viewPort) {
+ this.startPos = 0;
+ this.size = 0;
+ this.metaData = metaData;
+ this.rows = new Array();
+ this.updateInProgress = false;
+ this.viewPort = viewPort;
+ this.maxBufferSize = metaData.getLargeBufferSize() * 2;
+ this.maxFetchSize = metaData.getLargeBufferSize();
+ this.lastOffset = 0;
+ },
+
+ getBlankRow: function() {
+ if (!this.blankRow ) {
+ this.blankRow = new Array();
+ for ( var i=0; i < this.metaData.columnCount ; i++ )
+ this.blankRow[i] = " ";
+ }
+ return this.blankRow;
+ },
+
+ loadRows: function(ajaxResponse) {
+ var rowsElement = ajaxResponse.getElementsByTagName('rows')[0];
+ this.updateUI = rowsElement.getAttribute("update_ui") == "true"
+ var newRows = new Array()
+ var trs = rowsElement.getElementsByTagName("tr");
+ for ( var i=0 ; i < trs.length; i++ ) {
+ var row = newRows[i] = new Array();
+ var cells = trs[i].getElementsByTagName("td");
+ for ( var j=0; j < cells.length ; j++ ) {
+ var cell = cells[j];
+ var convertSpaces = cell.getAttribute("convert_spaces") == "true";
+ var cellContent = RicoUtil.getContentAsString(cell);
+ row[j] = convertSpaces ? this.convertSpaces(cellContent) : cellContent;
+ if (!row[j])
+ row[j] = ' ';
+ }
+ }
+ return newRows;
+ },
+
+ update: function(ajaxResponse, start) {
+ var newRows = this.loadRows(ajaxResponse);
+ if (this.rows.length == 0) { // initial load
+ this.rows = newRows;
+ this.size = this.rows.length;
+ this.startPos = start;
+ return;
+ }
+ if (start > this.startPos) { //appending
+ if (this.startPos + this.rows.length < start) {
+ this.rows = newRows;
+ this.startPos = start;//
+ } else {
+ this.rows = this.rows.concat( newRows.slice(0, newRows.length));
+ if (this.rows.length > this.maxBufferSize) {
+ var fullSize = this.rows.length;
+ this.rows = this.rows.slice(this.rows.length - this.maxBufferSize, this.rows.length)
+ this.startPos = this.startPos + (fullSize - this.rows.length);
+ }
+ }
+ } else { //prepending
+ if (start + newRows.length < this.startPos) {
+ this.rows = newRows;
+ } else {
+ this.rows = newRows.slice(0, this.startPos).concat(this.rows);
+ if (this.rows.length > this.maxBufferSize)
+ this.rows = this.rows.slice(0, this.maxBufferSize)
+ }
+ this.startPos = start;
+ }
+ this.size = this.rows.length;
+ },
+
+ clear: function() {
+ this.rows = new Array();
+ this.startPos = 0;
+ this.size = 0;
+ },
+
+ isOverlapping: function(start, size) {
+ return ((start < this.endPos()) && (this.startPos < start + size)) || (this.endPos() == 0)
+ },
+
+ isInRange: function(position) {
+ return (position >= this.startPos) && (position + this.metaData.getPageSize() <= this.endPos());
+ //&& this.size() != 0;
+ },
+
+ isNearingTopLimit: function(position) {
+ return position - this.startPos < this.metaData.getLimitTolerance();
+ },
+
+ endPos: function() {
+ return this.startPos + this.rows.length;
+ },
+
+ isNearingBottomLimit: function(position) {
+ return this.endPos() - (position + this.metaData.getPageSize()) < this.metaData.getLimitTolerance();
+ },
+
+ isAtTop: function() {
+ return this.startPos == 0;
+ },
+
+ isAtBottom: function() {
+ return this.endPos() == this.metaData.getTotalRows();
+ },
+
+ isNearingLimit: function(position) {
+ return ( !this.isAtTop() && this.isNearingTopLimit(position)) ||
+ ( !this.isAtBottom() && this.isNearingBottomLimit(position) )
+ },
+
+ getFetchSize: function(offset) {
+ var adjustedOffset = this.getFetchOffset(offset);
+ var adjustedSize = 0;
+ if (adjustedOffset >= this.startPos) { //apending
+ var endFetchOffset = this.maxFetchSize + adjustedOffset;
+ if (endFetchOffset > this.metaData.totalRows)
+ endFetchOffset = this.metaData.totalRows;
+ adjustedSize = endFetchOffset - adjustedOffset;
+ if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize){
+ adjustedSize = this.maxFetchSize;
+ }
+ } else {//prepending
+ var adjustedSize = this.startPos - adjustedOffset;
+ if (adjustedSize > this.maxFetchSize)
+ adjustedSize = this.maxFetchSize;
+ }
+ return adjustedSize;
+ },
+
+ getFetchOffset: function(offset) {
+ var adjustedOffset = offset;
+ if (offset > this.startPos) //apending
+ adjustedOffset = (offset > this.endPos()) ? offset : this.endPos();
+ else { //prepending
+ if (offset + this.maxFetchSize >= this.startPos) {
+ var adjustedOffset = this.startPos - this.maxFetchSize;
+ if (adjustedOffset < 0)
+ adjustedOffset = 0;
+ }
+ }
+ this.lastOffset = adjustedOffset;
+ return adjustedOffset;
+ },
+
+ getRows: function(start, count) {
+ var begPos = start - this.startPos
+ var endPos = begPos + count
+
+ // er? need more data...
+ if ( endPos > this.size )
+ endPos = this.size
+
+ var results = new Array()
+ var index = 0;
+ for ( var i=begPos ; i < endPos; i++ ) {
+ results[index++] = this.rows[i]
+ }
+ return results
+ },
+
+ convertSpaces: function(s) {
+ return s.split(" ").join(" ");
+ }
+
+};
+
+
+//Rico.GridViewPort --------------------------------------------------
+Rico.GridViewPort = Class.create();
+
+Rico.GridViewPort.prototype = {
+
+ initialize: function(table, rowHeight, visibleRows, buffer, liveGrid) {
+ this.lastDisplayedStartPos = 0;
+ this.div = table.parentNode;
+ this.table = table
+ this.rowHeight = rowHeight;
+ this.div.style.height = (this.rowHeight * visibleRows) + "px";
+ this.div.style.overflow = "hidden";
+ this.buffer = buffer;
+ this.liveGrid = liveGrid;
+ this.visibleRows = visibleRows + 1;
+ this.lastPixelOffset = 0;
+ this.startPos = 0;
+ },
+
+ populateRow: function(htmlRow, row) {
+ for (var j=0; j < row.length; j++) {
+ htmlRow.cells[j].innerHTML = row[j]
+ }
+ },
+
+ bufferChanged: function() {
+ this.refreshContents( parseInt(this.lastPixelOffset / this.rowHeight));
+ },
+
+ clearRows: function() {
+ if (!this.isBlank) {
+ this.liveGrid.table.className = this.liveGrid.options.loadingClass;
+ for (var i=0; i < this.visibleRows; i++)
+ this.populateRow(this.table.rows[i], this.buffer.getBlankRow());
+ this.isBlank = true;
+ }
+ },
+
+ clearContents: function() {
+ this.clearRows();
+ this.scrollTo(0);
+ this.startPos = 0;
+ this.lastStartPos = -1;
+ },
+
+ refreshContents: function(startPos) {
+ if (startPos == this.lastRowPos && !this.isPartialBlank && !this.isBlank) {
+ return;
+ }
+ if ((startPos + this.visibleRows < this.buffer.startPos)
+ || (this.buffer.startPos + this.buffer.size < startPos)
+ || (this.buffer.size == 0)) {
+ this.clearRows();
+ return;
+ }
+ this.isBlank = false;
+ var viewPrecedesBuffer = this.buffer.startPos > startPos
+ var contentStartPos = viewPrecedesBuffer ? this.buffer.startPos: startPos;
+ var contentEndPos = (this.buffer.startPos + this.buffer.size < startPos + this.visibleRows)
+ ? this.buffer.startPos + this.buffer.size
+ : startPos + this.visibleRows;
+ var rowSize = contentEndPos - contentStartPos;
+ var rows = this.buffer.getRows(contentStartPos, rowSize );
+ var blankSize = this.visibleRows - rowSize;
+ var blankOffset = viewPrecedesBuffer ? 0: rowSize;
+ var contentOffset = viewPrecedesBuffer ? blankSize: 0;
+
+ for (var i=0; i < rows.length; i++) {//initialize what we have
+ this.populateRow(this.table.rows[i + contentOffset], rows[i]);
+ }
+ for (var i=0; i < blankSize; i++) {// blank out the rest
+ this.populateRow(this.table.rows[i + blankOffset], this.buffer.getBlankRow());
+ }
+ this.isPartialBlank = blankSize > 0;
+ this.lastRowPos = startPos;
+
+ this.liveGrid.table.className = this.liveGrid.options.tableClass;
+ // Check if user has set a onRefreshComplete function
+ var onRefreshComplete = this.liveGrid.options.onRefreshComplete;
+ if (onRefreshComplete != null)
+ onRefreshComplete();
+ },
+
+ scrollTo: function(pixelOffset) {
+ if (this.lastPixelOffset == pixelOffset)
+ return;
+
+ this.refreshContents(parseInt(pixelOffset / this.rowHeight))
+ this.div.scrollTop = pixelOffset % this.rowHeight
+
+ this.lastPixelOffset = pixelOffset;
+ },
+
+ visibleHeight: function() {
+ return parseInt(RicoUtil.getElementsComputedStyle(this.div, 'height'));
+ }
+
+};
+
+
+Rico.LiveGridRequest = Class.create();
+Rico.LiveGridRequest.prototype = {
+ initialize: function( requestOffset, options ) {
+ this.requestOffset = requestOffset;
+ }
+};
+
+// Rico.LiveGrid -----------------------------------------------------
+
+Rico.LiveGrid = Class.create();
+
+Rico.LiveGrid.prototype = {
+
+ initialize: function( tableId, visibleRows, totalRows, url, options, ajaxOptions ) {
+
+ this.options = {
+ tableClass: $(tableId).className,
+ loadingClass: $(tableId).className,
+ scrollerBorderRight: '1px solid #ababab',
+ bufferTimeout: 20000,
+ sortAscendImg: 'images/sort_asc.gif',
+ sortDescendImg: 'images/sort_desc.gif',
+ sortImageWidth: 9,
+ sortImageHeight: 5,
+ ajaxSortURLParms: [],
+ onRefreshComplete: null,
+ requestParameters: null,
+ inlineStyles: true
+ };
+ Object.extend(this.options, options || {});
+
+ this.ajaxOptions = {parameters: null};
+ Object.extend(this.ajaxOptions, ajaxOptions || {});
+
+ this.tableId = tableId;
+ this.table = $(tableId);
+
+ this.addLiveGridHtml();
+
+ var columnCount = this.table.rows[0].cells.length;
+ this.metaData = new Rico.LiveGridMetaData(visibleRows, totalRows, columnCount, options);
+ this.buffer = new Rico.LiveGridBuffer(this.metaData);
+
+ var rowCount = this.table.rows.length;
+ this.viewPort = new Rico.GridViewPort(this.table,
+ this.table.offsetHeight/rowCount,
+ visibleRows,
+ this.buffer, this);
+ this.scroller = new Rico.LiveGridScroller(this,this.viewPort);
+ this.options.sortHandler = this.sortHandler.bind(this);
+
+ if ( $(tableId + '_header') )
+ this.sort = new Rico.LiveGridSort(tableId + '_header', this.options)
+
+ this.processingRequest = null;
+ this.unprocessedRequest = null;
+
+ this.initAjax(url);
+ if ( this.options.prefetchBuffer || this.options.prefetchOffset > 0) {
+ var offset = 0;
+ if (this.options.offset ) {
+ offset = this.options.offset;
+ this.scroller.moveScroll(offset);
+ this.viewPort.scrollTo(this.scroller.rowToPixel(offset));
+ }
+ if (this.options.sortCol) {
+ this.sortCol = options.sortCol;
+ this.sortDir = options.sortDir;
+ }
+ this.requestContentRefresh(offset);
+ }
+ },
+
+ addLiveGridHtml: function() {
+ // Check to see if need to create a header table.
+ if (this.table.getElementsByTagName("thead").length > 0){
+ // Create Table this.tableId+'_header'
+ var tableHeader = this.table.cloneNode(true);
+ tableHeader.setAttribute('id', this.tableId+'_header');
+ tableHeader.setAttribute('class', this.table.className+'_header');
+
+ // Clean up and insert
+ for( var i = 0; i < tableHeader.tBodies.length; i++ )
+ tableHeader.removeChild(tableHeader.tBodies[i]);
+ this.table.deleteTHead();
+ this.table.parentNode.insertBefore(tableHeader,this.table);
+ }
+
+ new Insertion.Before(this.table, "<div id='"+this.tableId+"_container'></div>");
+ this.table.previousSibling.appendChild(this.table);
+ new Insertion.Before(this.table,"<div id='"+this.tableId+"_viewport' style='float:left;'></div>");
+ this.table.previousSibling.appendChild(this.table);
+ },
+
+
+ resetContents: function() {
+ this.scroller.moveScroll(0);
+ this.buffer.clear();
+ this.viewPort.clearContents();
+ },
+
+ sortHandler: function(column) {
+ if(!column) return ;
+ this.sortCol = column.name;
+ this.sortDir = column.currentSort;
+
+ this.resetContents();
+ this.requestContentRefresh(0)
+ },
+
+ adjustRowSize: function() {
+
+ },
+
+ setTotalRows: function( newTotalRows ) {
+ this.resetContents();
+ this.metaData.setTotalRows(newTotalRows);
+ this.scroller.updateSize();
+ },
+
+ initAjax: function(url) {
+ ajaxEngine.registerRequest( this.tableId + '_request', url );
+ ajaxEngine.registerAjaxObject( this.tableId + '_updater', this );
+ },
+
+ invokeAjax: function() {
+ },
+
+ handleTimedOut: function() {
+ //server did not respond in 4 seconds... assume that there could have been
+ //an error or something, and allow requests to be processed again...
+ this.processingRequest = null;
+ this.processQueuedRequest();
+ },
+
+ fetchBuffer: function(offset) {
+ if ( this.buffer.isInRange(offset) &&
+ !this.buffer.isNearingLimit(offset)) {
+ return;
+ }
+ if (this.processingRequest) {
+ this.unprocessedRequest = new Rico.LiveGridRequest(offset);
+ return;
+ }
+ var bufferStartPos = this.buffer.getFetchOffset(offset);
+ this.processingRequest = new Rico.LiveGridRequest(offset);
+ this.processingRequest.bufferOffset = bufferStartPos;
+ var fetchSize = this.buffer.getFetchSize(offset);
+ var partialLoaded = false;
+
+ var queryString
+ if (this.options.requestParameters)
+ queryString = this._createQueryString(this.options.requestParameters, 0);
+
+ queryString = (queryString == null) ? '' : queryString+'&';
+ queryString = queryString+'id='+this.tableId+'&page_size='+fetchSize+'&offset='+bufferStartPos;
+ if (this.sortCol)
+ queryString = queryString+'&sort_col='+escape(this.sortCol)+'&sort_dir='+this.sortDir;
+
+ this.ajaxOptions.parameters = queryString;
+
+ ajaxEngine.sendRequest( this.tableId + '_request', this.ajaxOptions );
+
+ this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout);
+
+ },
+
+ setRequestParams: function() {
+ this.options.requestParameters = [];
+ for ( var i=0 ; i < arguments.length ; i++ )
+ this.options.requestParameters[i] = arguments[i];
+ },
+
+ requestContentRefresh: function(contentOffset) {
+ this.fetchBuffer(contentOffset);
+ },
+
+ ajaxUpdate: function(ajaxResponse) {
+ try {
+ clearTimeout( this.timeoutHandler );
+ this.buffer.update(ajaxResponse,this.processingRequest.bufferOffset);
+ this.viewPort.bufferChanged();
+ }
+ catch(err) {}
+ finally {this.processingRequest = null; }
+ this.processQueuedRequest();
+ },
+
+ _createQueryString: function( theArgs, offset ) {
+ var queryString = ""
+ if (!theArgs)
+ return queryString;
+
+ for ( var i = offset ; i < theArgs.length ; i++ ) {
+ if ( i != offset )
+ queryString += "&";
+
+ var anArg = theArgs[i];
+
+ if ( anArg.name != undefined && anArg.value != undefined ) {
+ queryString += anArg.name + "=" + escape(anArg.value);
+ }
+ else {
+ var ePos = anArg.indexOf('=');
+ var argName = anArg.substring( 0, ePos );
+ var argValue = anArg.substring( ePos + 1 );
+ queryString += argName + "=" + escape(argValue);
+ }
+ }
+ return queryString;
+ },
+
+ processQueuedRequest: function() {
+ if (this.unprocessedRequest != null) {
+ this.requestContentRefresh(this.unprocessedRequest.requestOffset);
+ this.unprocessedRequest = null
+ }
+ }
+};
+
+
+//-------------------- ricoLiveGridSort.js
+Rico.LiveGridSort = Class.create();
+
+Rico.LiveGridSort.prototype = {
+
+ initialize: function(headerTableId, options) {
+ this.headerTableId = headerTableId;
+ this.headerTable = $(headerTableId);
+ this.options = options;
+ this.setOptions();
+ this.applySortBehavior();
+
+ if ( this.options.sortCol ) {
+ this.setSortUI( this.options.sortCol, this.options.sortDir );
+ }
+ },
+
+ setSortUI: function( columnName, sortDirection ) {
+ var cols = this.options.columns;
+ for ( var i = 0 ; i < cols.length ; i++ ) {
+ if ( cols[i].name == columnName ) {
+ this.setColumnSort(i, sortDirection);
+ break;
+ }
+ }
+ },
+
+ setOptions: function() {
+ // preload the images...
+ new Image().src = this.options.sortAscendImg;
+ new Image().src = this.options.sortDescendImg;
+
+ this.sort = this.options.sortHandler;
+ if ( !this.options.columns )
+ this.options.columns = this.introspectForColumnInfo();
+ else {
+ // allow client to pass { columns: [ ["a", true], ["b", false] ] }
+ // and convert to an array of Rico.TableColumn objs...
+ this.options.columns = this.convertToTableColumns(this.options.columns);
+ }
+ },
+
+ applySortBehavior: function() {
+ var headerRow = this.headerTable.rows[0];
+ var headerCells = headerRow.cells;
+ for ( var i = 0 ; i < headerCells.length ; i++ ) {
+ this.addSortBehaviorToColumn( i, headerCells[i] );
+ }
+ },
+
+ addSortBehaviorToColumn: function( n, cell ) {
+ if ( this.options.columns[n].isSortable() ) {
+ cell.id = this.headerTableId + '_' + n;
+ cell.style.cursor = 'pointer';
+ cell.onclick = this.headerCellClicked.bindAsEventListener(this);
+ cell.innerHTML = cell.innerHTML + '<span id="' + this.headerTableId + '_img_' + n + '">'
+ + '   </span>';
+ }
+ },
+
+ // event handler....
+ headerCellClicked: function(evt) {
+ var eventTarget = evt.target ? evt.target : evt.srcElement;
+ var cellId = eventTarget.id;
+ var columnNumber = parseInt(cellId.substring( cellId.lastIndexOf('_') + 1 ));
+ var sortedColumnIndex = this.getSortedColumnIndex();
+ if ( sortedColumnIndex != -1 ) {
+ if ( sortedColumnIndex != columnNumber ) {
+ this.removeColumnSort(sortedColumnIndex);
+ this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
+ }
+ else
+ this.toggleColumnSort(sortedColumnIndex);
+ }
+ else
+ this.setColumnSort(columnNumber, Rico.TableColumn.SORT_ASC);
+
+ if (this.options.sortHandler) {
+ this.options.sortHandler(this.options.columns[columnNumber]);
+ }
+ },
+
+ removeColumnSort: function(n) {
+ this.options.columns[n].setUnsorted();
+ this.setSortImage(n);
+ },
+
+ setColumnSort: function(n, direction) {
+ if(isNaN(n)) return ;
+ this.options.columns[n].setSorted(direction);
+ this.setSortImage(n);
+ },
+
+ toggleColumnSort: function(n) {
+ this.options.columns[n].toggleSort();
+ this.setSortImage(n);
+ },
+
+ setSortImage: function(n) {
+ var sortDirection = this.options.columns[n].getSortDirection();
+
+ var sortImageSpan = $( this.headerTableId + '_img_' + n );
+ if ( sortDirection == Rico.TableColumn.UNSORTED )
+ sortImageSpan.innerHTML = '  ';
+ else if ( sortDirection == Rico.TableColumn.SORT_ASC )
+ sortImageSpan.innerHTML = '  <img width="' + this.options.sortImageWidth + '" ' +
+ 'height="'+ this.options.sortImageHeight + '" ' +
+ 'src="' + this.options.sortAscendImg + '"/>';
+ else if ( sortDirection == Rico.TableColumn.SORT_DESC )
+ sortImageSpan.innerHTML = '  <img width="' + this.options.sortImageWidth + '" ' +
+ 'height="'+ this.options.sortImageHeight + '" ' +
+ 'src="' + this.options.sortDescendImg + '"/>';
+ },
+
+ getSortedColumnIndex: function() {
+ var cols = this.options.columns;
+ for ( var i = 0 ; i < cols.length ; i++ ) {
+ if ( cols[i].isSorted() )
+ return i;
+ }
+
+ return -1;
+ },
+
+ introspectForColumnInfo: function() {
+ var columns = new Array();
+ var headerRow = this.headerTable.rows[0];
+ var headerCells = headerRow.cells;
+ for ( var i = 0 ; i < headerCells.length ; i++ )
+ columns.push( new Rico.TableColumn( this.deriveColumnNameFromCell(headerCells[i],i), true ) );
+ return columns;
+ },
+
+ convertToTableColumns: function(cols) {
+ var columns = new Array();
+ for ( var i = 0 ; i < cols.length ; i++ )
+ columns.push( new Rico.TableColumn( cols[i][0], cols[i][1] ) );
+ return columns;
+ },
+
+ deriveColumnNameFromCell: function(cell,columnNumber) {
+ var cellContent = cell.innerText != undefined ? cell.innerText : cell.textContent;
+ return cellContent ? cellContent.toLowerCase().split(' ').join('_') : "col_" + columnNumber;
+ }
+};
+
+Rico.TableColumn = Class.create();
+
+Rico.TableColumn.UNSORTED = 0;
+Rico.TableColumn.SORT_ASC = "ASC";
+Rico.TableColumn.SORT_DESC = "DESC";
+
+Rico.TableColumn.prototype = {
+ initialize: function(name, sortable) {
+ this.name = name;
+ this.sortable = sortable;
+ this.currentSort = Rico.TableColumn.UNSORTED;
+ },
+
+ isSortable: function() {
+ return this.sortable;
+ },
+
+ isSorted: function() {
+ return this.currentSort != Rico.TableColumn.UNSORTED;
+ },
+
+ getSortDirection: function() {
+ return this.currentSort;
+ },
+
+ toggleSort: function() {
+ if ( this.currentSort == Rico.TableColumn.UNSORTED || this.currentSort == Rico.TableColumn.SORT_DESC )
+ this.currentSort = Rico.TableColumn.SORT_ASC;
+ else if ( this.currentSort == Rico.TableColumn.SORT_ASC )
+ this.currentSort = Rico.TableColumn.SORT_DESC;
+ },
+
+ setUnsorted: function(direction) {
+ this.setSorted(Rico.TableColumn.UNSORTED);
+ },
+
+ setSorted: function(direction) {
+ // direction must by one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC...
+ this.currentSort = direction;
+ }
+
+};
+
+
+//-------------------- ricoUtil.js
+var RicoUtil = {
+
+ getElementsComputedStyle: function ( htmlElement, cssProperty, mozillaEquivalentCSS) {
+ if ( arguments.length == 2 )
+ mozillaEquivalentCSS = cssProperty;
+
+ var el = $(htmlElement);
+ if ( el.currentStyle )
+ return el.currentStyle[cssProperty];
+ else
+ return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozillaEquivalentCSS);
+ },
+
+ createXmlDocument : function() {
+ if (document.implementation && document.implementation.createDocument) {
+ var doc = document.implementation.createDocument("", "", null);
+
+ if (doc.readyState == null) {
+ doc.readyState = 1;
+ doc.addEventListener("load", function () {
+ doc.readyState = 4;
+ if (typeof doc.onreadystatechange == "function")
+ doc.onreadystatechange();
+ }, false);
+ }
+
+ return doc;
+ }
+
+ if (window.ActiveXObject)
+ return Try.these(
+ function() { return new ActiveXObject('MSXML2.DomDocument') },
+ function() { return new ActiveXObject('Microsoft.DomDocument')},
+ function() { return new ActiveXObject('MSXML.DomDocument') },
+ function() { return new ActiveXObject('MSXML3.DomDocument') }
+ ) || false;
+
+ return null;
+ },
+
+ getContentAsString: function( parentNode ) {
+ return parentNode.xml != undefined ?
+ this._getContentAsStringIE(parentNode) :
+ this._getContentAsStringMozilla(parentNode);
+ },
+
+ _getContentAsStringIE: function(parentNode) {
+ var contentStr = "";
+ for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
+ var n = parentNode.childNodes[i];
+ if (n.nodeType == 4) {
+ contentStr += n.nodeValue;
+ }
+ else {
+ contentStr += n.xml;
+ }
+ }
+ return contentStr;
+ },
+
+ _getContentAsStringMozilla: function(parentNode) {
+ var xmlSerializer = new XMLSerializer();
+ var contentStr = "";
+ for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
+ var n = parentNode.childNodes[i];
+ if (n.nodeType == 4) { // CDATA node
+ contentStr += n.nodeValue;
+ }
+ else {
+ contentStr += xmlSerializer.serializeToString(n);
+ }
+ }
+ return contentStr;
+ },
+
+ toViewportPosition: function(element) {
+ return this._toAbsolute(element,true);
+ },
+
+ toDocumentPosition: function(element) {
+ return this._toAbsolute(element,false);
+ },
+
+ /**
+ * Compute the elements position in terms of the window viewport
+ * so that it can be compared to the position of the mouse (dnd)
+ * This is additions of all the offsetTop,offsetLeft values up the
+ * offsetParent hierarchy, ...taking into account any scrollTop,
+ * scrollLeft values along the way...
+ *
+ * IE has a bug reporting a correct offsetLeft of elements within a
+ * a relatively positioned parent!!!
+ **/
+ _toAbsolute: function(element,accountForDocScroll) {
+
+ if ( navigator.userAgent.toLowerCase().indexOf("msie") == -1 )
+ return this._toAbsoluteMozilla(element,accountForDocScroll);
+
+ var x = 0;
+ var y = 0;
+ var parent = element;
+ while ( parent ) {
+
+ var borderXOffset = 0;
+ var borderYOffset = 0;
+ if ( parent != element ) {
+ var borderXOffset = parseInt(this.getElementsComputedStyle(parent, "borderLeftWidth" ));
+ var borderYOffset = parseInt(this.getElementsComputedStyle(parent, "borderTopWidth" ));
+ borderXOffset = isNaN(borderXOffset) ? 0 : borderXOffset;
+ borderYOffset = isNaN(borderYOffset) ? 0 : borderYOffset;
+ }
+
+ x += parent.offsetLeft - parent.scrollLeft + borderXOffset;
+ y += parent.offsetTop - parent.scrollTop + borderYOffset;
+ parent = parent.offsetParent;
+ }
+
+ if ( accountForDocScroll ) {
+ x -= this.docScrollLeft();
+ y -= this.docScrollTop();
+ }
+
+ return { x:x, y:y };
+ },
+
+ /**
+ * Mozilla did not report all of the parents up the hierarchy via the
+ * offsetParent property that IE did. So for the calculation of the
+ * offsets we use the offsetParent property, but for the calculation of
+ * the scrollTop/scrollLeft adjustments we navigate up via the parentNode
+ * property instead so as to get the scroll offsets...
+ *
+ **/
+ _toAbsoluteMozilla: function(element,accountForDocScroll) {
+ var x = 0;
+ var y = 0;
+ var parent = element;
+ while ( parent ) {
+ x += parent.offsetLeft;
+ y += parent.offsetTop;
+ parent = parent.offsetParent;
+ }
+
+ parent = element;
+ while ( parent &&
+ parent != document.body &&
+ parent != document.documentElement ) {
+ if ( parent.scrollLeft )
+ x -= parent.scrollLeft;
+ if ( parent.scrollTop )
+ y -= parent.scrollTop;
+ parent = parent.parentNode;
+ }
+
+ if ( accountForDocScroll ) {
+ x -= this.docScrollLeft();
+ y -= this.docScrollTop();
+ }
+
+ return { x:x, y:y };
+ },
+
+ docScrollLeft: function() {
+ if ( window.pageXOffset )
+ return window.pageXOffset;
+ else if ( document.documentElement && document.documentElement.scrollLeft )
+ return document.documentElement.scrollLeft;
+ else if ( document.body )
+ return document.body.scrollLeft;
+ else
+ return 0;
+ },
+
+ docScrollTop: function() {
+ if ( window.pageYOffset )
+ return window.pageYOffset;
+ else if ( document.documentElement && document.documentElement.scrollTop )
+ return document.documentElement.scrollTop;
+ else if ( document.body )
+ return document.body.scrollTop;
+ else
+ return 0;
+ }
+
+};
define('_TB_dateFormat', 'Date format');
define('_TB_dateFormat_VAL', "%e/%m/%g");
-define('_TB_Notify', 'Send e-mail notification on ping receipt');
+define('_TB_ajaxEnabled', 'Enable Ajax ?');
define('_TB_NotifyEmail', 'Which e-mail address to send these notification to?');
+define('_TB_NotifyEmailBlog', 'Which e-mail address to send these notification to?');
+
define('_TB_DropTable', 'Clear the database when uninstalling');
define('_TB_HideUrl', 'Hide external URL');
define('_TB_ItemAcceptPing', 'Accept pings');
define('_TB_isAcceptWOLink_VAL', 'default|default|yes|yes|no|no');
define('_TB_isAcceptWOLinkDef_VAL', 'yes|yes|no (block)|block|no (ignore)|ignore');
-?>
\ No newline at end of file
define('_TB_dateFormat', 'ÆüÉդηÁ¼°');
define('_TB_dateFormat_VAL', "%Y/%m/%d %H:%I");
-define('_TB_Notify', 'ping¼õÉÕ»þ¤Ë¥á¡¼¥ëÁ÷¿®¤¹¤ë¤«?');
-define('_TB_NotifyEmail', 'ping¼õÉÕ»þ¤Î¥á¡¼¥ëÁ÷¿®Àè');
+define('_TB_ajaxEnabled', '´ÉÍý²èÌ̤ÇAjax¤ò͸ú¤Ë¤¹¤ë¤«');
+define('_TB_NotifyEmail', 'ping¼õÉÕ»þ¤Î¥á¡¼¥ëÁ÷¿®Àè(;¤Ç¶èÀڤäÆÊ£¿ôÆþÎϲÄǽ)');
+define('_TB_NotifyEmailBlog', 'ping¼õÉÕ»þ¤Î¥á¡¼¥ëÁ÷¿®Àè(;¤Ç¶èÀڤäÆÊ£¿ôÆþÎϲÄǽ)');
+
define('_TB_DropTable', '¥×¥é¥°¥¤¥ó¤Îºï½ü»þ¤Ë¥Ç¡¼¥¿¤òºï½ü¤¹¤ë¤«?');
define('_TB_HideUrl', '°ìÍ÷ɽ¼¨¤ÎºÝ¤Ë³°Éô¤ÎURL¤ò¥ê¥À¥¤¥ì¥¯¥È¤ËÊÑ´¹¤¹¤ë¤«?');
define('_TB_ItemAcceptPing', 'TB¤ò¼õÉÕ¤¹¤ë¤«?');
define('_TB_isAcceptWOLink_VAL', '¥Ö¥í¥°¥Ç¥Õ¥©¥ë¥È¤Ë½¾¤¦|default|¤Ï¤¤|yes|¤¤¤¤¤¨|no');
define('_TB_isAcceptWOLinkDef_VAL', '¤Ï¤¤|yes|¤¤¤¤¤¨(ÊÝα)|block|¤¤¤¤¤¨(̵»ë)|ignore');
-?>
\ No newline at end of file
define('_TB_dateFormat', '日付の形式');
define('_TB_dateFormat_VAL', "%Y/%m/%d %H:%I");
-define('_TB_Notify', 'ping受付時にメール送信するか?');
-define('_TB_NotifyEmail', 'ping受付時のメール送信先');
+
+define('_TB_ajaxEnabled', '管理画面でAjaxを有効にするか');
+define('_TB_NotifyEmail', 'ping受付時のメール送信先(;で区切って複数入力可能)');
+define('_TB_NotifyEmailBlog', 'ping受付時のメール送信先(;で区切って複数入力可能)');
+
define('_TB_DropTable', 'プラグインの削除時にデータを削除するか?');
define('_TB_HideUrl', '一覧表示の際に外部のURLをリダイレクトに変換するか?');
define('_TB_ItemAcceptPing', 'TBを受付するか?');
define('_TB_isAcceptWOLink_VAL', 'ブログデフォルトに従う|default|はい|yes|いいえ|no');
define('_TB_isAcceptWOLinkDef_VAL', 'はい|yes|いいえ(保留)|block|いいえ(無視)|ignore');
-?>
\ No newline at end of file
#!/bin/bash -x
-FILES=`find japanese-utf8.templates -name '*html'`
+FILES=`find japanese-utf8.templates -name '*ml'`
for utf8file in $FILES
do
}
}
}
-
-?>
\ No newline at end of file
<table>
<thead>
<tr>
+ <th>Date</th>
<th>Story</th>
<th>Title, Blog and Excerpt</th>
- <th>Date</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<?php while (list(,$item) = each ($items)): ?>
<tr onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
<td>
+ <?php echo str_replace(' ', ' ', date("Y-m-d @ H:i",$item['timestamp']));?>
+ </td>
+ <td>
<a href="<? echo $item['story_url']; ?>"><?php echo $item['story'];?></a>
</td>
<td>
<?php echo $item['excerpt'];?>
</td>
<td>
- <?php echo str_replace(' ', ' ', date("Y-m-d @ H:i",$item['timestamp']));?>
- </td>
- <td>
<a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=block&tb='.$item['id'].'&next=all&start='.$start),ENT_QUOTES);?>"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
</td>
<td>
--- /dev/null
+<?php global $manager; ?>
+<h2>
+ All trackbacks
+</h2>
+
+<div id="showingLabel">Showing 1 - 5 of <?php echo $count ; ?></div>
+
+<div style="width: 100%">
+<div id="viewPort" style="float:left; width: 420px">
+<table id="tb_grid" style="border:0; margin:0; width: 400px">
+ <thead>
+ <tr>
+ <th style="width:80px">Date</th>
+ <th style="width:120px">Story</th>
+ <th >Title, Blog and Excerpt</th>
+ <th style="width:20px"> </th>
+ <th style="width:20px"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+</div>
+<div style="clear:both"></div>
+
+<script>
+//<![CDATA[
+ function updateHeader( liveGrid, offset ) {
+ $('showingLabel').innerHTML = "Showing " + (offset+1) + " - " + (offset+liveGrid.metaData.getPageSize()) + " of " + liveGrid.metaData.getTotalRows();
+ }
+
+ function loadGrid() {
+ var width = $('content').offsetWidth
+ $('viewPort').style.width = width + 'px';
+ $('tb_grid').style.width = ( width - 40 ) + 'px';
+
+ var max = <?php echo $count; ?>;
+ var params = ['action=ajax','type=all','ticket=' + '<?php echo $ticket ;?>'];
+ var opts = {
+ prefetchBuffer: true
+ ,prefetchOffset: 50
+ ,onscroll: updateHeader
+ ,requestParameters: params
+ ,sortAscendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_asc.gif'
+ ,sortDescendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_desc.gif'
+ ,columns: [ ["date", true], ["item", true], ["title", true], ["ban", false], ["del", false] ]
+ };
+ var liveGrid = new Rico.LiveGrid('tb_grid',5 , max, '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php', opts);
+ }
+
+ window.onload = loadGrid;
+//]]>
+</script>
--- /dev/null
+<?php global $manager; ?>
+<h2>
+ Blocked Trackbacks
+</h2>
+
+<ul>
+ <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_clear&next=blocked'),ENT_QUOTES); ?>">繝悶Ο繝�繧ッ縺輔l縺溘ヨ繝ゥ繝�繧ッ繝舌ャ繧ッ縺ョ繧ッ繝ェ繧「</a></li>
+ <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_spamclear&next=blocked'),ENT_QUOTES); ?>">spam蛻、螳壹&繧後◆繝医Λ繝�繧ッ繝舌ャ繧ッ縺ョ繧ッ繝ェ繧「</a></li>
+</ul>
+
+<div id="showingLabel">Showing 1 - 5 of <?php echo $count ; ?></div>
+
+<div style="float:left; width: 100%">
+<div id="viewPort" style="float:left; width: 620px">
+<table id="tb_grid" style="border:0; margin:0; width: 600px">
+ <thead>
+ <tr>
+ <th style="width:80px">Date</th>
+ <th style="width:120px">Story</th>
+ <th >Title, Blog and Excerpt</th>
+ <th style="width:20px"> </th>
+ <th style="width:20px"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ <tr style="height:110px" onmouseover='focusRow(this);' onmouseout='blurRow(this);'>
+ <td style="width:80px"> </td>
+ <td style="width:120px"> </td>
+ <td > </td>
+ <td style="width:20px"> </td>
+ <td style="width:20px"> </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+</div>
+<div style="clear:both"></div>
+
+<script>
+//<![CDATA[
+ function updateHeader( liveGrid, offset ) {
+ $('showingLabel').innerHTML = "Showing " + (offset+1) + " - " + (offset+liveGrid.metaData.getPageSize()) + " of " + liveGrid.metaData.getTotalRows();
+ }
+
+ function loadGrid() {
+ var width = $('content').offsetWidth
+ $('viewPort').style.width = width + 'px';
+ $('tb_grid').style.width = (width - 40) + 'px';
+
+ var max = <?php echo $count; ?>;
+ var params = ['action=ajax','type=blocked','ticket=' + '<?php echo $ticket ;?>'];
+ var opts = {
+ prefetchBuffer: true
+ ,prefetchOffset: 50
+ ,onscroll: updateHeader
+ ,requestParameters: params
+ ,sortAscendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_asc.gif'
+ ,sortDescendImg: '<?php echo $CONF['PluginURL'].'trackback/';?>images/sort_desc.gif'
+ ,columns: [ ["date", true], ["item", true], ["title", true], ["ban", false], ["del", false] ]
+ };
+ var liveGrid = new Rico.LiveGrid('tb_grid',5 , max, '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php', opts);
+ }
+
+ window.onload = loadGrid;
+//]]>
+</script>
<?php global $manager?>
+
+<script type="text/javascript" src="<?php echo $CONF['PluginURL'].'trackback/js/'?>prototype.js"></script>
+<script type="text/javascript" src="<?php echo $CONF['PluginURL'].'trackback/js/'?>rico.js"></script>
+
<h2>Trackback</h2>
<ul>
</li>
<li>
<img border="0" src="<?php echo $plugindirurl?>silk/plugin_edit.png" />
- <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['AdminURL'].'index.php?action=pluginoptions&plugid='.$plugid);?>">Plugin Options</a>
+ <a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['AdminURL'].'index.php?action=pluginoptions&plugid='.$plugid),ENT_QUOTES);?>">Plugin Options</a>
</li>
</ul>
\ No newline at end of file