* ==========================================================================================
*/
- // Compatiblity with Nucleus < = 2.0
- if (!function_exists('sql_table')) { function sql_table($name) { return 'nucleus_' . $name; } }
-
-
class NP_TrackBack extends NucleusPlugin {
-
var $useCurl = 1; // use curl? 2:precheck+read by curl, 1: read by curl 0: fread
//modify start+++++++++
';
if($offset)
$query .= ' LIMIT '.intval($offset).', ' .intval($amount);
- $res = mysql_query($query);
+ $res = sql_query($query);
while ($row = mysql_fetch_array($res))
{
//mod by cles end
/*
- $res = mysql_query('
+ $res = sql_query('
SELECT
url,
md5(url) as urlHash,
$query .= ' LIMIT '.intval($amount);
if( $amount != 0)
- $res = mysql_query($query);
+ $res = sql_query($query);
$gVars = array(
'action' => $this->getTrackBackUrl(intval($tb_id)),
ORDER BY
timestamp DESC
';
- $result = mysql_query($q);
+ $result = sql_query($q);
$total = mysql_result($result,0,0);
if($amount != -1 && $total > $amount){
echo "\t\t\t<description>".htmlspecialchars($excerpt, ENT_QUOTES)."</description>\n";
$query = 'SELECT url, blog_name, excerpt, title, UNIX_TIMESTAMP(timestamp) as timestamp FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' AND block = 0 ORDER BY timestamp DESC';
- $res = mysql_query($query);
+ $res = sql_query($query);
while ($o = mysql_fetch_object($res))
{
// No need to do conversion, because it is already UTF-8
//modify end+++++++++
// 4. Save data in the DB
- $res = @mysql_query('
+ $res = @sql_query('
SELECT
tb_id, block, spam
FROM
{
// Existing TB, update it
/*
- $res = @mysql_query('
+ $res = @sql_query('
UPDATE
'.sql_table('plugin_tb').'
SET
//modify start+++++++++
$rows = mysql_fetch_assoc($res);
$spam = ( $rows['block'] || $rows['spam'] ) ? true : false;
- $res = @mysql_query('
+ $res = @sql_query('
UPDATE
'.sql_table('plugin_tb').'
SET
';
//modify end+++++++++
- $res = @mysql_query($query);
+ $res = @sql_query($query);
if (!$res) {
return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error() . $query;
function redirect($tb_id, $urlHash){
global $CONF;
$query = 'SELECT url FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' and md5(url)="'.$urlHash.'"';
- $res = mysql_query($query);
+ $res = sql_query($query);
$url = $CONF['SiteURL'];
function event_RetrieveTrackback($data) {
- $res = mysql_query('
+ $res = sql_query('
SELECT
url,
title,
{
// Check to see if the cache contains this link
- $res = mysql_query('SELECT url, title FROM '.sql_table('plugin_tb_lookup').' WHERE link=\''.mysql_real_escape_string($link).'\'');
+ $res = sql_query('SELECT url, title FROM '.sql_table('plugin_tb_lookup').' WHERE link=\''.mysql_real_escape_string($link).'\'');
if ($row = mysql_fetch_array($res))
{
$convertedTitle = $title;
/*
// Store in cache
- $res = mysql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($title)."')");
+ $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($title)."')");
*/
// Store in cache
- $res = mysql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($convertedTitle)."')");
+ $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($convertedTitle)."')");
//modify end+++++++++
$title = $this->_decode_entities($title);
$uri = html_entity_decode($uri, ENT_COMPAT);
// Store in cache
- $res = mysql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','')");
+ $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','')");
return array (
$uri, $uri
}
// Store in cache
- $res = mysql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','','')");
+ $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','','')");
return array ('', '');
}
/**************************************************************************************/
/* Internal helper functions for dealing with encodings and entities */
- var $entities_cp1251 = array (
- '€' => '€',
- '‚' => '‚',
- 'ƒ' => 'ƒ',
- '„' => '„',
- '…' => '…',
- '†' => '†',
- '‡' => '‡',
- 'ˆ' => 'ˆ',
- '‰' => '‰',
- 'Š' => 'Š',
- '‹' => '‹',
- 'Œ' => 'Œ',
- 'Ž' => 'Ž',
- '‘' => '‘',
- '’' => '’',
- '“' => '“',
- '”' => '”',
- '•' => '•',
- '–' => '–',
- '—' => '—',
- '˜' => '˜',
- '™' => '™',
- 'š' => 'š',
- '›' => '›',
- 'œ' => 'œ',
- 'ž' => 'ž',
- 'Ÿ' => 'Ÿ',
- );
-
var $entities_default = array (
'"' => '"',
'&' => '&',
'>' => '>',
);
- var $entities_latin = array (
- ' ' => ' ',
- '¡' => '¡',
- '¢' => '¢',
- '£' => '£',
- '¤' => '¤',
- '¥' => '¥',
- '¦' => '¦',
- '§' => '§',
- '¨' => '¨',
- '©' => '©',
- 'ª' => 'ª',
- '«' => '«',
- '¬' => '¬',
- '­' => '­',
- '®' => '®',
- '¯' => '¯',
- '°' => '°',
- '±' => '±',
- '²' => '²',
- '³' => '³',
- '´' => '´',
- 'µ' => 'µ',
- '¶' => '¶',
- '·' => '·',
- '¸' => '¸',
- '¹' => '¹',
- 'º' => 'º',
- '»' => '»',
- '¼' => '¼',
- '½' => '½',
- '¾' => '¾',
- '¿' => '¿',
- 'À' => 'À',
- 'Á' => 'Á',
- 'Â' => 'Â',
- 'Ã' => 'Ã',
- 'Ä' => 'Ä',
- 'Å' => 'Å',
- 'Æ' => 'Æ',
- 'Ç' => 'Ç',
- 'È' => 'È',
- 'É' => 'É',
- 'Ê' => 'Ê',
- 'Ë' => 'Ë',
- 'Ì' => 'Ì',
- 'Í' => 'Í',
- 'Î' => 'Î',
- 'Ï' => 'Ï',
- 'Ð' => 'Ð',
- 'Ñ' => 'Ñ',
- 'Ò' => 'Ò',
- 'Ó' => 'Ó',
- 'Ô' => 'Ô',
- 'Õ' => 'Õ',
- 'Ö' => 'Ö',
- '×' => '×',
- 'Ø' => 'Ø',
- 'Ù' => 'Ù',
- 'Ú' => 'Ú',
- 'Û' => 'Û',
- 'Ü' => 'Ü',
- 'Ý' => 'Ý',
- 'Þ' => 'Þ',
- 'ß' => 'ß',
- 'à' => 'à',
- 'á' => 'á',
- 'â' => 'â',
- 'ã' => 'ã',
- 'ä' => 'ä',
- 'å' => 'å',
- 'æ' => 'æ',
- 'ç' => 'ç',
- 'è' => 'è',
- 'é' => 'é',
- 'ê' => 'ê',
- 'ë' => 'ë',
- 'ì' => 'ì',
- 'í' => 'í',
- 'î' => 'î',
- 'ï' => 'ï',
- 'ð' => 'ð',
- 'ñ' => 'ñ',
- 'ò' => 'ò',
- 'ó' => 'ó',
- 'ô' => 'ô',
- 'õ' => 'õ',
- 'ö' => 'ö',
- '÷' => '÷',
- 'ø' => 'ø',
- 'ù' => 'ù',
- 'ú' => 'ú',
- 'û' => 'û',
- 'ü' => 'ü',
- 'ý' => 'ý',
- 'þ' => 'þ',
- 'ÿ' => 'ÿ',
- );
-
- var $entities_extended = array (
- 'Œ' => 'Œ',
- 'œ' => 'å',
- 'Š' => 'Š',
- 'š' => 'š',
- 'Ÿ' => 'Ÿ',
- 'ˆ' => 'ˆ',
- '˜' => '˜',
- '&esnp;' => ' ',
- ' ' => ' ',
- ' ' => ' ',
- '‌' => '‌',
- '‍' => '‍',
- '‎' => '‎',
- '‏' => '‏',
- '–' => '–',
- '—' => '—',
- '‘' => '‘',
- '’' => '’',
- '‚' => '‚',
- '“' => '“',
- '”' => '”',
- '„' => '„',
- '†' => '†',
- '‡' => '‡',
- '‰' => '‰',
- '‹' => '‹',
- '›' => '›',
- '€' => '€',
- 'ƒ' => 'ƒ',
- 'Α' => 'Α',
- 'Β' => 'Β',
- 'Γ' => 'Γ',
- 'Δ' => 'Δ',
- 'Ε' => 'Ε',
- 'Ζ' => 'Ζ',
- 'Η' => 'Η',
- 'Θ' => 'Θ',
- 'Ι' => 'Ι',
- 'Κ' => 'Κ',
- 'Λ' => 'Λ',
- 'Μ' => 'Μ',
- 'Ν' => 'Ν',
- 'Ξ' => 'Ξ',
- 'Ο' => 'Ο',
- 'Π' => 'Π',
- 'Ρ' => 'Ρ',
- 'Σ' => 'Σ',
- 'Τ' => 'Τ',
- 'Υ' => 'Υ',
- 'Φ' => 'Φ',
- 'Χ' => 'Χ',
- 'Ψ' => 'Ψ',
- 'Ω' => 'Ω',
- 'α' => 'α',
- 'β' => 'β',
- 'γ' => 'γ',
- 'δ' => 'δ',
- 'ε' => 'ε',
- 'ζ' => 'ζ',
- 'η' => 'η',
- 'θ' => 'θ',
- 'ι' => 'ι',
- 'κ' => 'κ',
- 'λ' => 'λ',
- 'μ' => 'μ',
- 'ν' => 'ν',
- 'ξ' => 'ξ',
- 'ο' => 'ο',
- 'π' => 'π',
- 'ρ' => 'ρ',
- 'ς' => 'ς',
- 'σ' => 'σ',
- 'τ' => 'τ',
- 'υ' => 'υ',
- 'φ' => 'φ',
- 'χ' => 'χ',
- 'ψ' => 'ψ',
- 'ω' => 'ω',
- 'ϑ' => 'ϑ',
- 'ϒ' => 'ϒ',
- 'ϖ' => 'ϖ',
- '•' => '•',
- '…' => '…',
- '′' => '′',
- '″' => '″',
- '‾' => '‾',
- '⁄' => '⁄',
- '℘' => '℘',
- 'ℑ' => 'ℑ',
- 'ℜ' => 'ℜ',
- '™' => '™',
- 'ℵ' => 'ℵ',
- '←' => '←',
- '↑' => '↑',
- '→' => '→',
- '↓' => '↓',
- '↔' => '↔',
- '↵' => '↵',
- '⇐' => '⇐',
- '⇑' => '⇑',
- '⇒' => '⇒',
- '⇓' => '⇓',
- '⇔' => '⇔',
- '∀' => '∀',
- '∂' => '∂',
- '∃' => '∃',
- '∅' => '∅',
- '∇' => '∇',
- '∈' => '∈',
- '∉' => '∉',
- '∋' => '∋',
- '∏' => '∏',
- '∑' => '∑',
- '−' => '−',
- '∗' => '∗',
- '√' => '√',
- '∝' => '∝',
- '∞' => '∞',
- '∠' => '∠',
- '∧' => '∧',
- '∨' => '∨',
- '∩' => '∩',
- '∪' => '∪',
- '∫' => '∫',
- '∴' => '∴',
- '∼' => '∼',
- '≅' => '≅',
- '≈' => '≈',
- '≠' => '≠',
- '≡' => '≡',
- '≤' => '≤',
- '≥' => '≥',
- '⊂' => '⊂',
- '⊃' => '⊃',
- '⊄' => '⊄',
- '⊆' => '⊆',
- '⊇' => '⊇',
- '⊕' => '⊕',
- '⊗' => '⊗',
- '⊥' => '⊥',
- '⋅' => '⋅',
- '⌈' => '⌈',
- '⌉' => '⌉',
- '⌊' => '⌊',
- '⌋' => '⌋',
- '⟨' => '〈',
- '⟩' => '〉',
- '◊' => '◊',
- '♠' => '♠',
- '♣' => '♣',
- '♥' => '♥',
- '♦' => '♦',
- );
-
-
//modify start+++++++++
function _restore_to_utf8($contents)
{
/// Convert all hexadecimal entities to decimal entities
$string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "'&#'.hexdec('\\1').';'", $string);
-
- // Deal with invalid cp1251 numeric entities
- $string = strtr($string, $this->entities_cp1251);
+
+ global $_entities;
+ // Deal with invalid cp1251 numeric entities
+ $string = strtr($string, $_entities['cp1251']);
// Convert all named entities to numeric entities
$string = strtr($string, $this->entities_default);
- $string = strtr($string, $this->entities_latin);
- $string = strtr($string, $this->entities_extended);
+ $string = strtr($string, $_entities['named']);
// Convert all numeric entities to UTF-8
$string = preg_replace('/&#([0-9]+);/e', "'&#x'.dechex('\\1').';'", $string);
return $string;
}
- function _hex_to_utf8($s)
- {
- /* IN: string containing one hexadecimal Unicode character
- * OUT: string containing one binary UTF-8 character
- */
-
- $c = hexdec($s);
-
- if ($c < 0x80) {
- $str = chr($c);
- }
- else if ($c < 0x800) {
- $str = chr(0xC0 | $c>>6) . chr(0x80 | $c & 0x3F);
- }
- else if ($c < 0x10000) {
- $str = chr(0xE0 | $c>>12) . chr(0x80 | $c>>6 & 0x3F) . chr(0x80 | $c & 0x3F);
- }
- else if ($c < 0x200000) {
- $str = chr(0xF0 | $c>>18) . chr(0x80 | $c>>12 & 0x3F) . chr(0x80 | $c>>6 & 0x3F) . chr(0x80 | $c & 0x3F);
- }
-
- return $str;
+ function _hex_to_utf8($s){
+ return entity::_hex_to_utf8($s);
}
function _utf8_to_entities($string)
// save data in the DB
$query = 'INSERT INTO ' . sql_table('plugin_tb_lc') . " (tb_id, from_id) VALUES ('".intval($tb_id)."','".intval($itemid)."')";
- $res = @mysql_query($query);
+ $res = @sql_query($query);
if (!$res)
return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error();
}
// create SQL query
$query = 'SELECT t.from_id as from_id , i.ititle as ititle, i.ibody as ibody, i.itime as itime, i.iblog as iblog FROM '.sql_table('plugin_tb_lc').' as t, '.sql_table('item').' as i WHERE t.tb_id='.intval($tb_id) .' and i.inumber=t.from_id ORDER BY i.itime DESC';
- $res = mysql_query($query);
+ $res = sql_query($query);
$vars = array(
'tburl' => $this->getTrackBackUrl($tb_id)
if (!$this->canDelete($tb_id))
return 'You\'re not allowed to delete this trackback item';
$query = 'DELETE FROM ' . sql_table('plugin_tb_lc') . " WHERE tb_id='" . intval($tb_id) . "' and from_id='" . intval($from_id) ."'";
- mysql_query($query);
+ sql_query($query);
return '';
}
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 jp9'; }
+ function getVersion() { return '2.0.3 jp10'; }
function getDescription() { return _TB_DESCRIPTION; }
//modify start+++++++++
function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead', 'RetrieveTrackback', 'SendTrackback', 'InitSkinParse'); }
//modify end+++++++++
- function getMinNucleusVersion() { return 200; }
+ function getMinNucleusVersion() { return 330; }
function supportsFeature($feature) {
switch($feature) {
//mod by cles end
/* Create tables */
- mysql_query("
+ sql_query("
CREATE TABLE IF NOT EXISTS
".sql_table('plugin_tb')."
(
)
");
- mysql_query("
+ sql_query("
CREATE TABLE IF NOT EXISTS
".sql_table('plugin_tb_lookup')."
(
)
");
//modify start+++++++++
- @mysql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
- @mysql_query('CREATE TABLE IF NOT EXISTS ' . sql_table('plugin_tb_lc'). ' (tb_id int(11) not null, from_id int(11) not null, PRIMARY KEY (tb_id,from_id))');
+ @sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
+ @sql_query('CREATE TABLE IF NOT EXISTS ' . sql_table('plugin_tb_lc'). ' (tb_id int(11) not null, from_id int(11) not null, PRIMARY KEY (tb_id,from_id))');
//modify end+++++++++
}
function uninstall() {
if ($this->getOption('DropTable') == 'yes') {
- mysql_query ('DROP TABLE '.sql_table('plugin_tb'));
- mysql_query ('DROP TABLE '.sql_table('plugin_tb_lookup'));
- mysql_query ("DROP table ".sql_table('plugin_tb_lc'));
+ sql_query ('DROP TABLE '.sql_table('plugin_tb'));
+ sql_query ('DROP TABLE '.sql_table('plugin_tb_lookup'));
+ sql_query ("DROP table ".sql_table('plugin_tb_lc'));
}
}
if( !$sort_col ) $sort_col = $colname['date'];
$sort_dir = ( requestVar('sort_dir') == 'ASC' ) ? 'ASC' : 'DESC';
+
+ $rres = sql_query ("
+ SELECT
+ count(*) as count
+ FROM
+ ".sql_table('plugin_tb')." AS t,
+ ".sql_table('item')." AS i
+ WHERE
+ t.tb_id = i.inumber AND
+ ".$filter[$type]);
+ $rrow = mysql_fetch_array($rres);
+ $count = $rrow['count'];
- $rres = mysql_query ("
+ $rres = sql_query ("
SELECT
i.ititle AS story,
i.inumber AS story_id,
$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['title'] = preg_replace("/-+/","-",$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['blog_name'] = preg_replace("/-+/","-",$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['excerpt'] = preg_replace("/-+/","-",$rrow['excerpt']);
$rrow['url'] = htmlspecialchars($rrow['url'], ENT_QUOTES);
$oTemplate->set ('items', $items);
$oTemplate->template('templates/response_'.$type.'.xml');
break;
+
+ case 'dodelete':
+ $ids = explode(',', requestVar('ids'));
+
+ $safeids = array();
+ foreach( $ids as $id ){
+ $id = trim($id);
+ if( is_numeric($id) )
+ $safeids[] = $id;
+ }
+
+ if( count($safeids) > 0 ){
+ $safeids = implode(',',$safeids);
+
+ $res = sql_query(
+ ' DELETE FROM '
+ . sql_table('plugin_tb')
+ . ' WHERE id in (' . $safeids. ')'
+ );
+ $oTemplate->set ('message', $safeids . ' deleted.');
+ } else {
+ $oTemplate->set ('message', 'no rows deleted.');
+ }
+
+ $oTemplate->template('templates/response_dodelete.xml');
+ break;
+
+ case 'doblock':
+ $ids = explode(',', requestVar('ids'));
+
+ $safeids = array();
+ foreach( $ids as $id ){
+ $id = trim($id);
+ if( is_numeric($id) )
+ $safeids[] = $id;
+ }
+
+ if( count($safeids) > 0 ){
+ $safeids = implode(',',$safeids);
+
+ $res = sql_query(
+ ' UPDATE '
+ . sql_table('plugin_tb')
+ .' SET block = 1 '
+ . ' WHERE id in (' . $safeids. ')'
+ );
+ $oTemplate->set ('message', $safeids . ' blocked.');
+ } else {
+ $oTemplate->set ('message', 'no rows blocked.');
+ }
+
+ $oTemplate->template('templates/response_doblock.xml');
+ break;
+
+ case 'dounblock':
+ $ids = explode(',', requestVar('ids'));
+
+ $safeids = array();
+ foreach( $ids as $id ){
+ $id = trim($id);
+ if( is_numeric($id) )
+ $safeids[] = $id;
+ }
+
+ if( count($safeids) > 0 ){
+ $safeids = implode(',',$safeids);
+
+ $res = sql_query(
+ ' UPDATE '
+ . sql_table('plugin_tb')
+ .' SET block = 0 '
+ . ' WHERE id in (' . $safeids. ')'
+ );
+ $oTemplate->set ('message', $safeids . ' unblocked.');
+ } else {
+ $oTemplate->set ('message', 'no rows unblocked.');
+ }
+
+ $oTemplate->template('templates/response_dounblock.xml');
+ break;
}
// Create the admin area page
// Send out Content-type
- sendContentType('application/xhtml+xml', 'admin-trackback', _CHARSET);
+ //sendContentType('application/xhtml+xml', 'admin-trackback', _CHARSET);
$oPluginAdmin = new PluginAdmin('TrackBack');
if (!in_array($action, $aActionsNotToCheck)) {
if (!$manager->checkTicket()) doError(_ERROR_BADTICKET);
}
- $oPluginAdmin->start();
+
+ //$oPluginAdmin->start();
+ $oPluginAdmin->admin->pagehead();
//modify start+++++++++
$plug =& $oPluginAdmin->plugin;
//modify start+++++++++
case 'tableUpgrade':
- mysql_query("
+ sql_query("
CREATE TABLE IF NOT EXISTS
".sql_table('plugin_tb_lookup')."
(
CHANGE `blog_name` `blog_name` TEXT NOT NULL,
DROP PRIMARY KEY,
ADD `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;";
- $res = @mysql_query($q);
+ $res = @sql_query($q);
if (!$res){
echo 'Could not alter table: ' . mysql_error();
}else{
$tableVersion = 1;
$oTemplate->template('templates/updatetablefinished.html');
}
- @mysql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
+ @sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
break;
//modify end+++++++++
case 'block':
$tb = intRequestVar('tb');
- $res = mysql_query ("
+ $res = sql_query ("
UPDATE
".sql_table('plugin_tb')."
SET
$action = requestVar('next');
break;
case 'blocked_clear':
- $res = mysql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1");
+ $res = sql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1");
$action = requestVar('next');
break;
case 'blocked_spamclear':
- $res = mysql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1 and spam = 1");
+ $res = sql_query ("DELETE FROM ".sql_table('plugin_tb')." WHERE block = 1 and spam = 1");
$action = requestVar('next');
break;
case 'unblock':
$tb = intRequestVar('tb');
- $res = mysql_query ("
+ $res = sql_query ("
UPDATE
".sql_table('plugin_tb')."
SET
case 'delete':
$tb = intRequestVar('tb');
- $res = mysql_query ("
+ $res = sql_query ("
DELETE FROM
".sql_table('plugin_tb')."
WHERE
case 'blocked':
case 'all':
- $rres = mysql_query ("
+ $rres = sql_query ("
SELECT
COUNT(*) AS count
FROM
} else {\r $start = intRequestVar('start') ? intRequestVar('start') : 0;
$amount = intRequestVar('amount') ? intRequestVar('amount') : 25;
- $rres = mysql_query ("
+ $rres = sql_query ("
SELECT
i.ititle AS story,
i.inumber AS story_id,
$start = intRequestVar('start') ? intRequestVar('start') : 0;
$amount = intRequestVar('amount') ? intRequestVar('amount') : 25;
- $ires = mysql_query ("
+ $ires = sql_query ("
SELECT
ititle,
inumber
$story['id'] = $id;
$story['title'] = $irow['ititle'];
- $rres = mysql_query ("
+ $rres = sql_query ("
SELECT
COUNT(*) AS count
FROM
else
$count = 0;
- $rres = mysql_query ("
+ $rres = sql_query ("
SELECT
t.id AS id,
t.title AS title,
case 'index':
- $bres = mysql_query ("
+ $bres = sql_query ("
SELECT
bnumber AS bnumber,
bname AS bname,
while ($brow = mysql_fetch_array($bres))
{
- $ires = mysql_query ("
+ $ires = sql_query ("
SELECT
i.inumber AS inumber,
i.ititle AS ititle,
<h3>ÆüËܸìÈǹ¹¿·ÍúÎò</h3>
<ul>
+ <li>Version 2.0.3jp10 : (2007/**/**)</li>
+ <li>¡¡[Fixed] mysql_query()¤òsql_query()¤ËÊѹ¹</li>
+ <li>¡¡[Changed] ¼ÂÂλ²¾È¥Æ¡¼¥Ö¥ë¤Ë¤Ä¤¤¤ÆNucleusɸ½à¤â¤Î¤ò»È¤¦¤è¤¦¤Ë¤·¤¿</li>
+ <li>¡¡[Changed] ¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤¤ë¥Ð¡¼¥¸¥ç¥ó¤ò3.3°Ê¹ß¤·¤¿</li>
+ <li>¡¡[Changed] Rico¤ò2.0¤Ë¥¢¥Ã¥×¥Ç¡¼¥È¤·¤¿¤Î¤Ëȼ¤¤¡¢´ÉÍý²èÌ̤ε¡Ç½¤òÁý¶¯</li>
+
<li>Version 2.0.3jp9 : (2007/05/04)</li>
<li>¡¡[Added] doIf()¤òÄɲÃ(Nucleus 3.3¸þ¤±)</li>
<li>¡¡[Added] URL¤¬Ìµ¸ú¤Ê¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤·¤¿</li>
All trackbacks
</h2>
-<div id="showingLabel"><?php echo $count ; ?>·ïÃæ 1 - 5 ·ïÌܤòɽ¼¨¤·¤Æ¤¤¤Þ¤¹</div>
+<div id="message" style="color: red;"></div>
-<div style="width: 100%">
-<div id="viewPort" style="float:left; width: 420px">
-<table id="tb_grid" style="border:0; margin:0; width: 400px">
+<div style="width: 95%">
+<span id="tb_grid_bookmark"></span>
+
+<table id="tb_grid" style="border:0; margin:0;">
+ <colgroup>
+ <col style="width:25px;" />
+ <col style="width:40px;" />
+ <col style="width:70px;" />
+ <col style="width:150px;" />
+ <col style="width:200px;"/>
+ <col style="width:25px;" />
+ </colgroup>
<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>
+ <th> </th>
+ <th>id</th>
+ <th>Date</th>
+ <th>Story</th>
+ <th>Title, Blog and Excerpt</th>
+ <th> </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()) + "·ïÌܤòɽ¼¨¤·¤Æ¤¤¤Þ¤¹¡£";
- }
+¾åµ¤ÇÁªÂò¤·¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò°ì³ç¤·¤Æ½èÍý¤·¤Þ¤¹
+<a href="#" onclick="javascript: doDelete()"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
+<a href="#" onclick="javascript: doBlock()"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
+</div>
- function loadGrid() {
- var width = $('content').offsetWidth
- $('viewPort').style.width = width + 'px';
- $('tb_grid').style.width = ( width - 40 ) + 'px';
+<!--
+<textarea id='tb_grid_debugmsgs' rows='5' cols='80' style='font-size:smaller;'></textarea>
+-->
- 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);
- }
+<script type="text/javascript">
+//<![CDATA[
+ Rico.loadModule('LiveGridAjax');
+ Rico.loadModule('LiveGridMenu');
+ Rico.include('translations/livegrid_ja.js');
+ Rico.include('ricoAjaxEngine.js');
+
+ Rico.onLoad( function() {
+ var params = [
+ 'action=ajax',
+ 'type=all',
+ 'ticket=<?php echo $ticket ;?>'
+ ];
+
+ var cb = new Rico.TableColumn.checkbox('1','0');
+ var colspec = [
+ {canHide:false, type:'control', control:cb, ClassName:'aligncenter'},
+ {type:'raw'},
+ {type:'raw'},
+ ,
+ ,
+ ,
+ ];
+
+ var opts = {
+ saveColumnInfo : {width:true, filter:false, sort:false},
+ menuEvent : 'none',
+ frozenColumns : 2,
+ canSortDefault : true,
+ canHideDefault : true,
+ allowColResize : true,
+ canFilterDefault: false,
+ highlightElem : 'none',
+ columnSpecs : colspec
+ };
+
+ buffer = new Rico.Buffer.AjaxSQL('<?php echo $CONF['PluginURL'].'trackback/';?>grid.php',
+ {TimeOut:10, requestParameters:params, sortParmFmt: 'displayName'}
+ );
+ orderGrid=new Rico.LiveGrid ('tb_grid', buffer, opts);
+ orderGrid.menu=new Rico.GridMenu({});
+
+ // ajaxEngine
+ ajaxEngine = new Rico.AjaxEngine;
+ ajaxEngine.registerRequest('updateData', '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php' );
+ ajaxEngine.registerAjaxElement('message');
+ });
- window.onload = loadGrid;
+ function checkUpdateIds(){
+ var updateIds = [];
+ Rico.writeDebugMsg('check updated rows');
+ for(var i = 0; i < buffer.size; i++){
+ row = buffer.rows[i];
+ if( row[0].content && row[0].content == '1' ){
+ updateIds.push(row[1].content);
+ Rico.writeDebugMsg('id: '+row[1].content+' updated');
+ }
+ }
+ return updateIds;
+ }
+
+ function doBlock(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+ var params = [
+ 'action=doblock',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
+
+ function doDelete(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+
+ var params = [
+ 'action=dodelete',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
//]]>
</script>
<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 id="message" style="color: red;"></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">
+<div style="width: 95%">
+<span id="tb_grid_bookmark"></span>
+
+<table id="tb_grid" style="border:0; margin:0;">
+ <colgroup>
+ <col style="width:25px;" />
+ <col style="width:40px;" />
+ <col style="width:70px;" />
+ <col style="width:150px;" />
+ <col style="width:200px;"/>
+ <col style="width:25px;" />
+ </colgroup>
<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>
+ <th> </th>
+ <th>id</th>
+ <th>Date</th>
+ <th>Story</th>
+ <th>Title, Blog and Excerpt</th>
+ <th> </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>
+¾åµ¤ÇÁªÂò¤·¤¿¥È¥é¥Ã¥¯¥Ð¥Ã¥¯¤ò°ì³ç¤·¤Æ½èÍý¤·¤Þ¤¹
+<a href="#" onclick="javascript: doUnblock()"><img alt="Unblock" border="0" src="<?php echo $plugindirurl;?>silk/accept.png" /></a>
+<a href="#" onclick="javascript: doDelete()"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
</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';
+<!--
+<textarea id='tb_grid_debugmsgs' rows='5' cols='80' style='font-size:smaller;'></textarea>
+-->
- 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);
- }
+<script type="text/javascript">
+//<![CDATA[
+ Rico.loadModule('LiveGridAjax');
+ Rico.loadModule('LiveGridMenu');
+ Rico.include('translations/livegrid_ja.js');
+ Rico.include('ricoAjaxEngine.js');
+
+ Rico.onLoad( function() {
+ var params = [
+ 'action=ajax',
+ 'type=blocked',
+ 'ticket=<?php echo $ticket ;?>'
+ ];
+
+ var cb = new Rico.TableColumn.checkbox('1','0');
+ var colspec = [
+ {canHide:false, type:'control', control:cb, ClassName:'aligncenter'},
+ {type:'raw'},
+ {type:'raw'},
+ ,
+ ,
+ ,
+ ];
+
+ var opts = {
+ saveColumnInfo : {width:true, filter:false, sort:false},
+ menuEvent : 'none',
+ frozenColumns : 2,
+ canSortDefault : true,
+ canHideDefault : true,
+ allowColResize : true,
+ canFilterDefault: false,
+ highlightElem : 'none',
+ columnSpecs : colspec
+ };
+
+ buffer = new Rico.Buffer.AjaxSQL('<?php echo $CONF['PluginURL'].'trackback/';?>grid.php',
+ {TimeOut:10, requestParameters:params, sortParmFmt: 'displayName'}
+ );
+ orderGrid=new Rico.LiveGrid ('tb_grid', buffer, opts);
+ orderGrid.menu=new Rico.GridMenu({});
+
+ // ajaxEngine
+ ajaxEngine = new Rico.AjaxEngine;
+ ajaxEngine.registerRequest('updateData', '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php' );
+ ajaxEngine.registerAjaxElement('message');
+ });
- window.onload = loadGrid;
+ function checkUpdateIds(){
+ var updateIds = [];
+ Rico.writeDebugMsg('check updated rows');
+ for(var i = 0; i < buffer.size; i++){
+ row = buffer.rows[i];
+ if( row[0].content && row[0].content == '1' ){
+ updateIds.push(row[1].content);
+ Rico.writeDebugMsg('id: '+row[1].content+' updated');
+ }
+ }
+ return updateIds;
+ }
+
+ function doUnBlock(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+ var params = [
+ 'action=dounblock',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
+
+ function doDelete(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+
+ var params = [
+ 'action=dodelete',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
//]]>
</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>
+<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/rico.js"></script>
+
<ul>
<li>
<img border="0" src="<?php echo $plugindirurl?>silk/application_view_list.png" />
-<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php 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="<?php 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; ?>
+ <response type="object" id="tb_grid_updater">
+ <rowcount><?php echo $count; ?></rowcount>
+ <rows update_ui="true" offset="<?php echo $start; ?>" >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>0</td>
+ <td><?php echo $item['id'];?></td>
+ <td>
+ <?php echo date("Y-m-d H:i:s",$item['timestamp']);?>
+ </td>
+ <td>
+ <!--
+ <a href="<?php 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['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ -->
+ </td>
+ <td></td>
+ </tr>
+ <?php endwhile; ?>
</rows>
</response>
</ajax-response>
-<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
<?php global $manager; ?>
<ajax-response>
<response type="object" id='tb_grid_updater'>
+ <rowcount><?php echo $count; ?></rowcount>
<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="<?php 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; ?>
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>0</td>
+ <td><?php echo $item['id'];?></td>
+ <td>
+ <?php echo date("Y-m-d H:i:s",$item['timestamp']);?>
+ </td>
+ <td>
+ <!--
+ <a href="<?php 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" />';?>
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ -->
+ </td>
+ <td></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="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
<h3>日本語版更新履歴</h3>
<ul>
+ <li>Version 2.0.3jp10 : (2007/**/**)</li>
+ <li> [Fixed] mysql_query()をsql_query()に変更</li>
+ <li> [Changed] 実体参照テーブルについてNucleus標準ものを使うようにした</li>
+ <li> [Changed] インストールできるバージョンを3.3以降した</li>
+ <li> [Changed] Ricoを2.0にアップデートしたのに伴い、管理画面の機能を増強</li>
+
<li>Version 2.0.3jp9 : (2007/05/04)</li>
<li> [Added] doIf()を追加(Nucleus 3.3向け)</li>
<li> [Added] URLが無効なトラックバックを無視するようにした</li>
All trackbacks
</h2>
-<div id="showingLabel"><?php echo $count ; ?>件中 1 - 5 件目を表示しています</div>
+<div id="message" style="color: red;"></div>
-<div style="width: 100%">
-<div id="viewPort" style="float:left; width: 420px">
-<table id="tb_grid" style="border:0; margin:0; width: 400px">
+<div style="width: 95%">
+<span id="tb_grid_bookmark"></span>
+
+<table id="tb_grid" style="border:0; margin:0;">
+ <colgroup>
+ <col style="width:25px;" />
+ <col style="width:40px;" />
+ <col style="width:70px;" />
+ <col style="width:150px;" />
+ <col style="width:200px;"/>
+ <col style="width:25px;" />
+ </colgroup>
<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>
+ <th> </th>
+ <th>id</th>
+ <th>Date</th>
+ <th>Story</th>
+ <th>Title, Blog and Excerpt</th>
+ <th> </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()) + "件目を表示しています。";
- }
+上記で選択したトラックバックを一括して処理します
+<a href="#" onclick="javascript: doDelete()"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
+<a href="#" onclick="javascript: doBlock()"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
+</div>
- function loadGrid() {
- var width = $('content').offsetWidth
- $('viewPort').style.width = width + 'px';
- $('tb_grid').style.width = ( width - 40 ) + 'px';
+<!--
+<textarea id='tb_grid_debugmsgs' rows='5' cols='80' style='font-size:smaller;'></textarea>
+-->
- 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);
- }
+<script type="text/javascript">
+//<![CDATA[
+ Rico.loadModule('LiveGridAjax');
+ Rico.loadModule('LiveGridMenu');
+ Rico.include('translations/livegrid_ja.js');
+ Rico.include('ricoAjaxEngine.js');
+
+ Rico.onLoad( function() {
+ var params = [
+ 'action=ajax',
+ 'type=all',
+ 'ticket=<?php echo $ticket ;?>'
+ ];
+
+ var cb = new Rico.TableColumn.checkbox('1','0');
+ var colspec = [
+ {canHide:false, type:'control', control:cb, ClassName:'aligncenter'},
+ {type:'raw'},
+ {type:'raw'},
+ ,
+ ,
+ ,
+ ];
+
+ var opts = {
+ saveColumnInfo : {width:true, filter:false, sort:false},
+ menuEvent : 'none',
+ frozenColumns : 2,
+ canSortDefault : true,
+ canHideDefault : true,
+ allowColResize : true,
+ canFilterDefault: false,
+ highlightElem : 'none',
+ columnSpecs : colspec
+ };
+
+ buffer = new Rico.Buffer.AjaxSQL('<?php echo $CONF['PluginURL'].'trackback/';?>grid.php',
+ {TimeOut:10, requestParameters:params, sortParmFmt: 'displayName'}
+ );
+ orderGrid=new Rico.LiveGrid ('tb_grid', buffer, opts);
+ orderGrid.menu=new Rico.GridMenu({});
+
+ // ajaxEngine
+ ajaxEngine = new Rico.AjaxEngine;
+ ajaxEngine.registerRequest('updateData', '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php' );
+ ajaxEngine.registerAjaxElement('message');
+ });
- window.onload = loadGrid;
+ function checkUpdateIds(){
+ var updateIds = [];
+ Rico.writeDebugMsg('check updated rows');
+ for(var i = 0; i < buffer.size; i++){
+ row = buffer.rows[i];
+ if( row[0].content && row[0].content == '1' ){
+ updateIds.push(row[1].content);
+ Rico.writeDebugMsg('id: '+row[1].content+' updated');
+ }
+ }
+ return updateIds;
+ }
+
+ function doBlock(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+ var params = [
+ 'action=doblock',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
+
+ function doDelete(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+
+ var params = [
+ 'action=dodelete',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
//]]>
</script>
<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 id="message" style="color: red;"></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">
+<div style="width: 95%">
+<span id="tb_grid_bookmark"></span>
+
+<table id="tb_grid" style="border:0; margin:0;">
+ <colgroup>
+ <col style="width:25px;" />
+ <col style="width:40px;" />
+ <col style="width:70px;" />
+ <col style="width:150px;" />
+ <col style="width:200px;"/>
+ <col style="width:25px;" />
+ </colgroup>
<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>
+ <th> </th>
+ <th>id</th>
+ <th>Date</th>
+ <th>Story</th>
+ <th>Title, Blog and Excerpt</th>
+ <th> </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>
+上記で選択したトラックバックを一括して処理します
+<a href="#" onclick="javascript: doUnblock()"><img alt="Unblock" border="0" src="<?php echo $plugindirurl;?>silk/accept.png" /></a>
+<a href="#" onclick="javascript: doDelete()"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
</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';
+<!--
+<textarea id='tb_grid_debugmsgs' rows='5' cols='80' style='font-size:smaller;'></textarea>
+-->
- 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);
- }
+<script type="text/javascript">
+//<![CDATA[
+ Rico.loadModule('LiveGridAjax');
+ Rico.loadModule('LiveGridMenu');
+ Rico.include('translations/livegrid_ja.js');
+ Rico.include('ricoAjaxEngine.js');
+
+ Rico.onLoad( function() {
+ var params = [
+ 'action=ajax',
+ 'type=blocked',
+ 'ticket=<?php echo $ticket ;?>'
+ ];
+
+ var cb = new Rico.TableColumn.checkbox('1','0');
+ var colspec = [
+ {canHide:false, type:'control', control:cb, ClassName:'aligncenter'},
+ {type:'raw'},
+ {type:'raw'},
+ ,
+ ,
+ ,
+ ];
+
+ var opts = {
+ saveColumnInfo : {width:true, filter:false, sort:false},
+ menuEvent : 'none',
+ frozenColumns : 2,
+ canSortDefault : true,
+ canHideDefault : true,
+ allowColResize : true,
+ canFilterDefault: false,
+ highlightElem : 'none',
+ columnSpecs : colspec
+ };
+
+ buffer = new Rico.Buffer.AjaxSQL('<?php echo $CONF['PluginURL'].'trackback/';?>grid.php',
+ {TimeOut:10, requestParameters:params, sortParmFmt: 'displayName'}
+ );
+ orderGrid=new Rico.LiveGrid ('tb_grid', buffer, opts);
+ orderGrid.menu=new Rico.GridMenu({});
+
+ // ajaxEngine
+ ajaxEngine = new Rico.AjaxEngine;
+ ajaxEngine.registerRequest('updateData', '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php' );
+ ajaxEngine.registerAjaxElement('message');
+ });
- window.onload = loadGrid;
+ function checkUpdateIds(){
+ var updateIds = [];
+ Rico.writeDebugMsg('check updated rows');
+ for(var i = 0; i < buffer.size; i++){
+ row = buffer.rows[i];
+ if( row[0].content && row[0].content == '1' ){
+ updateIds.push(row[1].content);
+ Rico.writeDebugMsg('id: '+row[1].content+' updated');
+ }
+ }
+ return updateIds;
+ }
+
+ function doUnBlock(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+ var params = [
+ 'action=dounblock',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
+
+ function doDelete(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+
+ var params = [
+ 'action=dodelete',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
//]]>
</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>
+<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/rico.js"></script>
+
<ul>
<li>
<img border="0" src="<?php echo $plugindirurl?>silk/application_view_list.png" />
-<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php 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="<?php 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; ?>
+ <response type="object" id="tb_grid_updater">
+ <rowcount><?php echo $count; ?></rowcount>
+ <rows update_ui="true" offset="<?php echo $start; ?>" >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>0</td>
+ <td><?php echo $item['id'];?></td>
+ <td>
+ <?php echo date("Y-m-d H:i:s",$item['timestamp']);?>
+ </td>
+ <td>
+ <!--
+ <a href="<?php 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['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ -->
+ </td>
+ <td></td>
+ </tr>
+ <?php endwhile; ?>
</rows>
</response>
</ajax-response>
-<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
<?php global $manager; ?>
<ajax-response>
<response type="object" id='tb_grid_updater'>
+ <rowcount><?php echo $count; ?></rowcount>
<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="<?php 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; ?>
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>0</td>
+ <td><?php echo $item['id'];?></td>
+ <td>
+ <?php echo date("Y-m-d H:i:s",$item['timestamp']);?>
+ </td>
+ <td>
+ <!--
+ <a href="<?php 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" />';?>
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ -->
+ </td>
+ <td></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="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
+++ /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
+/* Prototype JavaScript framework, version 1.5.1
+ * (c) 2005-2007 Sam Stephenson
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.5.1',
+
+ Browser: {
+ IE: !!(window.attachEvent && !window.opera),
+ Opera: !!window.opera,
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
+ },
+
+ BrowserFeatures: {
+ XPath: !!document.evaluate,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ (document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__)
+ },
+
+ ScriptFragment: '<script[^>]*>([\u0001-\uFFFF]*?)</script>',
+ JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,
+
+ 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 (var property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+Object.extend(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;
+ }
+ },
+
+ toJSON: function(object) {
+ var type = typeof object;
+ switch(type) {
+ case 'undefined':
+ case 'function':
+ case 'unknown': return;
+ case 'boolean': return object.toString();
+ }
+ if (object === null) return 'null';
+ if (object.toJSON) return object.toJSON();
+ if (object.ownerDocument === document) return;
+ var results = [];
+ for (var property in object) {
+ var value = Object.toJSON(object[property]);
+ if (value !== undefined)
+ results.push(property.toJSON() + ': ' + value);
+ }
+ return '{' + results.join(', ') + '}';
+ },
+
+ keys: function(object) {
+ var keys = [];
+ for (var property in object)
+ keys.push(property);
+ return keys;
+ },
+
+ values: function(object) {
+ var values = [];
+ for (var property in object)
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function(object) {
+ return Object.extend({}, object);
+ }
+});
+
+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, args = $A(arguments), object = args.shift();
+ return function(event) {
+ return __method.apply(object, [event || window.event].concat(args));
+ }
+}
+
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ return this.toPaddedString(2, 16);
+ },
+
+ succ: function() {
+ return this + 1;
+ },
+
+ times: function(iterator) {
+ $R(0, this, true).each(iterator);
+ return this;
+ },
+
+ toPaddedString: function(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ },
+
+ toJSON: function() {
+ return isFinite(this) ? this.toString() : 'null';
+ }
+});
+
+Date.prototype.toJSON = function() {
+ return '"' + this.getFullYear() + '-' +
+ (this.getMonth() + 1).toPaddedString(2) + '-' +
+ this.getDate().toPaddedString(2) + 'T' +
+ this.getHours().toPaddedString(2) + ':' +
+ this.getMinutes().toPaddedString(2) + ':' +
+ this.getSeconds().toPaddedString(2) + '"';
+};
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0, length = arguments.length; i < 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() {
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ stop: function() {
+ if (!this.timer) return;
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.callback(this);
+ } finally {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+}
+Object.extend(String, {
+ interpret: function(value) {
+ return value == null ? '' : String(value);
+ },
+ specialChar: {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '\\': '\\\\'
+ }
+});
+
+Object.extend(String.prototype, {
+ gsub: function(pattern, replacement) {
+ var result = '', source = this, match;
+ replacement = arguments.callee.prepareReplacement(replacement);
+
+ while (source.length > 0) {
+ if (match = source.match(pattern)) {
+ result += source.slice(0, match.index);
+ result += String.interpret(replacement(match));
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source, source = '';
+ }
+ }
+ return result;
+ },
+
+ sub: function(pattern, replacement, count) {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = count === undefined ? 1 : count;
+
+ return this.gsub(pattern, function(match) {
+ if (--count < 0) return match[0];
+ return replacement(match);
+ });
+ },
+
+ scan: function(pattern, iterator) {
+ this.gsub(pattern, iterator);
+ return this;
+ },
+
+ truncate: function(length, truncation) {
+ length = length || 30;
+ truncation = truncation === undefined ? '...' : truncation;
+ return this.length > length ?
+ this.slice(0, length - truncation.length) + truncation : this;
+ },
+
+ strip: function() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
+
+ 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(function(script) { return eval(script) });
+ },
+
+ escapeHTML: function() {
+ var self = arguments.callee;
+ self.text.data = this;
+ return self.div.innerHTML;
+ },
+
+ unescapeHTML: function() {
+ var div = document.createElement('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0] ? (div.childNodes.length > 1 ?
+ $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
+ div.childNodes[0].nodeValue) : '';
+ },
+
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return {};
+
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var key = decodeURIComponent(pair.shift());
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
+ if (value != undefined) value = decodeURIComponent(value);
+
+ if (key in hash) {
+ if (hash[key].constructor != Array) hash[key] = [hash[key]];
+ hash[key].push(value);
+ }
+ else hash[key] = value;
+ }
+ return hash;
+ });
+ },
+
+ toArray: function() {
+ return this.split('');
+ },
+
+ succ: function() {
+ return this.slice(0, this.length - 1) +
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+ },
+
+ times: function(count) {
+ var result = '';
+ for (var i = 0; i < count; i++) result += this;
+ return result;
+ },
+
+ camelize: function() {
+ var parts = this.split('-'), len = parts.length;
+ if (len == 1) return parts[0];
+
+ var camelized = this.charAt(0) == '-'
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+ : parts[0];
+
+ for (var i = 1; i < len; i++)
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+ return camelized;
+ },
+
+ capitalize: function() {
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+ },
+
+ underscore: function() {
+ return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+ },
+
+ dasherize: function() {
+ return this.gsub(/_/,'-');
+ },
+
+ inspect: function(useDoubleQuotes) {
+ var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+ var character = String.specialChar[match[0]];
+ return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+ });
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ },
+
+ toJSON: function() {
+ return this.inspect(true);
+ },
+
+ unfilterJSON: function(filter) {
+ return this.sub(filter || Prototype.JSONFilter, '#{1}');
+ },
+
+ evalJSON: function(sanitize) {
+ var json = this.unfilterJSON();
+ try {
+ if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
+ return eval('(' + json + ')');
+ } catch (e) { }
+ throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+ },
+
+ include: function(pattern) {
+ return this.indexOf(pattern) > -1;
+ },
+
+ startsWith: function(pattern) {
+ return this.indexOf(pattern) === 0;
+ },
+
+ endsWith: function(pattern) {
+ var d = this.length - pattern.length;
+ return d >= 0 && this.lastIndexOf(pattern) === d;
+ },
+
+ empty: function() {
+ return this == '';
+ },
+
+ blank: function() {
+ return /^\s*$/.test(this);
+ }
+});
+
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+ escapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ },
+ unescapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+ if (typeof replacement == 'function') return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+Object.extend(String.prototype.escapeHTML, {
+ div: document.createElement('div'),
+ text: document.createTextNode('')
+});
+
+with (String.prototype.escapeHTML) div.appendChild(text);
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+ initialize: function(template, pattern) {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function(object) {
+ return this.template.gsub(this.pattern, function(match) {
+ var before = match[1];
+ if (before == '\\') return match[2];
+ return before + String.interpret(object[match[3]]);
+ });
+ }
+}
+
+var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');
+
+var Enumerable = {
+ each: function(iterator) {
+ var index = 0;
+ try {
+ this._each(function(value) {
+ iterator(value, index++);
+ });
+ } catch (e) {
+ if (e != $break) throw e;
+ }
+ return this;
+ },
+
+ eachSlice: function(number, iterator) {
+ var index = -number, slices = [], array = this.toArray();
+ while ((index += number) < array.length)
+ slices.push(array.slice(index, index+number));
+ return slices.map(iterator);
+ },
+
+ 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 = false;
+ 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 || Prototype.K)(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;
+ },
+
+ inGroupsOf: function(number, fillWith) {
+ fillWith = fillWith === undefined ? null : fillWith;
+ return this.eachSlice(number, function(slice) {
+ while(slice.length < number) slice.push(fillWith);
+ return slice;
+ });
+ },
+
+ 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.map(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 (result == undefined || value >= result)
+ result = value;
+ });
+ return result;
+ },
+
+ min: function(iterator) {
+ var result;
+ this.each(function(value, index) {
+ value = (iterator || Prototype.K)(value, index);
+ if (result == undefined || value < result)
+ 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.map(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.map();
+ },
+
+ 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) {
+ return iterator(collections.pluck(index));
+ });
+ },
+
+ size: function() {
+ return this.toArray().length;
+ },
+
+ 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, length = iterable.length; i < length; i++)
+ results.push(iterable[i]);
+ return results;
+ }
+}
+
+if (Prototype.Browser.WebKit) {
+ $A = Array.from = function(iterable) {
+ if (!iterable) return [];
+ if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
+ iterable.toArray) {
+ return iterable.toArray();
+ } else {
+ var results = [];
+ for (var i = 0, length = iterable.length; i < length; i++)
+ results.push(iterable[i]);
+ return results;
+ }
+ }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+ Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+ _each: function(iterator) {
+ for (var i = 0, length = this.length; i < 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 != null;
+ });
+ },
+
+ flatten: function() {
+ return this.inject([], function(array, value) {
+ return array.concat(value && 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, length = this.length; i < length; i++)
+ if (this[i] == object) return i;
+ return -1;
+ },
+
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ reduce: function() {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function(sorted) {
+ return this.inject([], function(array, value, index) {
+ if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+ array.push(value);
+ return array;
+ });
+ },
+
+ clone: function() {
+ return [].concat(this);
+ },
+
+ size: function() {
+ return this.length;
+ },
+
+ inspect: function() {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ },
+
+ toJSON: function() {
+ var results = [];
+ this.each(function(object) {
+ var value = Object.toJSON(object);
+ if (value !== undefined) results.push(value);
+ });
+ return '[' + results.join(', ') + ']';
+ }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string) {
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera){
+ Array.prototype.concat = function() {
+ var array = [];
+ for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ if (arguments[i].constructor == Array) {
+ for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+ array.push(arguments[i][j]);
+ } else {
+ array.push(arguments[i]);
+ }
+ }
+ return array;
+ }
+}
+var Hash = function(object) {
+ if (object instanceof Hash) this.merge(object);
+ else Object.extend(this, object || {});
+};
+
+Object.extend(Hash, {
+ toQueryString: function(obj) {
+ var parts = [];
+ parts.add = arguments.callee.addPair;
+
+ this.prototype._each.call(obj, function(pair) {
+ if (!pair.key) return;
+ var value = pair.value;
+
+ if (value && typeof value == 'object') {
+ if (value.constructor == Array) value.each(function(value) {
+ parts.add(pair.key, value);
+ });
+ return;
+ }
+ parts.add(pair.key, value);
+ });
+
+ return parts.join('&');
+ },
+
+ toJSON: function(object) {
+ var results = [];
+ this.prototype._each.call(object, function(pair) {
+ var value = Object.toJSON(pair.value);
+ if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
+ });
+ return '{' + results.join(', ') + '}';
+ }
+});
+
+Hash.toQueryString.addPair = function(key, value, prefix) {
+ key = encodeURIComponent(key);
+ if (value === undefined) this.push(key);
+ else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
+}
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+ _each: function(iterator) {
+ for (var key in this) {
+ var value = this[key];
+ if (value && value == Hash.prototype[key]) 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(this, function(mergedHash, pair) {
+ mergedHash[pair.key] = pair.value;
+ return mergedHash;
+ });
+ },
+
+ remove: function() {
+ var result;
+ for(var i = 0, length = arguments.length; i < length; i++) {
+ var value = this[arguments[i]];
+ if (value !== undefined){
+ if (result === undefined) result = value;
+ else {
+ if (result.constructor != Array) result = [result];
+ result.push(value)
+ }
+ }
+ delete this[arguments[i]];
+ }
+ return result;
+ },
+
+ toQueryString: function() {
+ return Hash.toQueryString(this);
+ },
+
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ },
+
+ toJSON: function() {
+ return Hash.toJSON(this);
+ }
+});
+
+function $H(object) {
+ if (object instanceof Hash) return object;
+ return new Hash(object);
+};
+
+// Safari iterates over shadowed properties
+if (function() {
+ var i = 0, Test = function(value) { this.key = value };
+ Test.prototype.key = 'foo';
+ for (var property in new Test('bar')) i++;
+ return i > 1;
+}()) Hash.prototype._each = function(iterator) {
+ var cache = [];
+ for (var key in this) {
+ var value = this[key];
+ if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
+ cache.push(key);
+ var pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+};
+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;
+ while (this.include(value)) {
+ iterator(value);
+ value = value.succ();
+ }
+ },
+
+ 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 XMLHttpRequest()},
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+ ) || false;
+ },
+
+ activeRequestCount: 0
+}
+
+Ajax.Responders = {
+ responders: [],
+
+ _each: function(iterator) {
+ this.responders._each(iterator);
+ },
+
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
+ },
+
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
+ },
+
+ dispatch: function(callback, request, transport, json) {
+ this.each(function(responder) {
+ if (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,
+ contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
+ parameters: ''
+ }
+ Object.extend(this.options, options || {});
+
+ this.options.method = this.options.method.toLowerCase();
+ if (typeof this.options.parameters == 'string')
+ this.options.parameters = this.options.parameters.toQueryParams();
+ }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ _complete: false,
+
+ initialize: function(url, options) {
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+ this.request(url);
+ },
+
+ request: function(url) {
+ this.url = url;
+ this.method = this.options.method;
+ var params = Object.clone(this.options.parameters);
+
+ if (!['get', 'post'].include(this.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.method;
+ this.method = 'post';
+ }
+
+ this.parameters = params;
+
+ if (params = Hash.toQueryString(params)) {
+ // when GET, append parameters to URL
+ if (this.method == 'get')
+ this.url += (this.url.include('?') ? '&' : '?') + params;
+ else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ params += '&_=';
+ }
+
+ try {
+ if (this.options.onCreate) this.options.onCreate(this.transport);
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+ this.transport.open(this.method.toUpperCase(), this.url,
+ this.options.asynchronous);
+
+ if (this.options.asynchronous)
+ setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ this.setRequestHeaders();
+
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+ this.transport.send(this.body);
+
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
+ this.onStateChange();
+
+ }
+ catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1 && !((readyState == 4) && this._complete))
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ setRequestHeaders: function() {
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
+
+ if (this.method == 'post') {
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
+ }
+
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
+
+ if (typeof extras.push == 'function')
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
+
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
+ },
+
+ success: function() {
+ return !this.transport.status
+ || (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ respondToReadyState: function(readyState) {
+ var state = Ajax.Request.Events[readyState];
+ var transport = this.transport, json = this.evalJSON();
+
+ if (state == 'Complete') {
+ try {
+ this._complete = true;
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ var contentType = this.getHeader('Content-type');
+ if (contentType && contentType.strip().
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if (state == 'Complete') {
+ // avoid memory leak in MSIE: clean up
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ getHeader: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) { return null }
+ },
+
+ evalJSON: function() {
+ try {
+ var json = this.getHeader('X-JSON');
+ return json ? json.evalJSON() : null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval((this.transport.responseText || '').unfilterJSON());
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ 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.container = {
+ success: (container.success || 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, param) {
+ this.updateContent();
+ onComplete(transport, param);
+ }).bind(this);
+
+ this.request(url);
+ },
+
+ updateContent: function() {
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
+ var response = this.transport.responseText;
+
+ if (!this.options.evalScripts) response = response.stripScripts();
+
+ if (receiver = $(receiver)) {
+ if (this.options.insertion)
+ new this.options.insertion(receiver, response);
+ else
+ receiver.update(response);
+ }
+
+ if (this.success()) {
+ 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.options.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);
+ }
+});
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
+ }
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+ document._getElementsByXPath = function(expression, parentElement) {
+ var results = [];
+ var query = document.evaluate(expression, $(parentElement) || document,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
+ results.push(query.snapshotItem(i));
+ return results;
+ };
+
+ document.getElementsByClassName = function(className, parentElement) {
+ var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+ return document._getElementsByXPath(q, parentElement);
+ }
+
+} else document.getElementsByClassName = function(className, parentElement) {
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ var elements = [], child;
+ for (var i = 0, length = children.length; i < length; i++) {
+ child = children[i];
+ if (Element.hasClassName(child, className))
+ elements.push(Element.extend(child));
+ }
+ return elements;
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element) var Element = {};
+
+Element.extend = function(element) {
+ var F = Prototype.BrowserFeatures;
+ if (!element || !element.tagName || element.nodeType == 3 ||
+ element._extended || F.SpecificElementExtensions || element == window)
+ return element;
+
+ var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
+ T = Element.Methods.ByTag;
+
+ // extend methods for all tags (Safari doesn't need this)
+ if (!F.ElementExtensions) {
+ Object.extend(methods, Element.Methods),
+ Object.extend(methods, Element.Methods.Simulated);
+ }
+
+ // extend methods for specific tags
+ if (T[tagName]) Object.extend(methods, T[tagName]);
+
+ for (var property in methods) {
+ var value = methods[property];
+ if (typeof value == 'function' && !(property in element))
+ element[property] = cache.findOrStore(value);
+ }
+
+ element._extended = Prototype.emptyFunction;
+ return element;
+};
+
+Element.extend.cache = {
+ findOrStore: function(value) {
+ return this[value] = this[value] || function() {
+ return value.apply(null, [this].concat($A(arguments)));
+ }
+ }
+};
+
+Element.Methods = {
+ visible: function(element) {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function(element) {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
+ },
+
+ hide: function(element) {
+ $(element).style.display = 'none';
+ return element;
+ },
+
+ show: function(element) {
+ $(element).style.display = '';
+ return element;
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ return element;
+ },
+
+ update: function(element, html) {
+ html = typeof html == 'undefined' ? '' : html.toString();
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ },
+
+ replace: function(element, html) {
+ element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
+ if (element.outerHTML) {
+ element.outerHTML = html.stripScripts();
+ } else {
+ var range = element.ownerDocument.createRange();
+ range.selectNodeContents(element);
+ element.parentNode.replaceChild(
+ range.createContextualFragment(html.stripScripts()), element);
+ }
+ setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ },
+
+ inspect: function(element) {
+ element = $(element);
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
+ },
+
+ recursivelyCollect: function(element, property) {
+ element = $(element);
+ var elements = [];
+ while (element = element[property])
+ if (element.nodeType == 1)
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function(element) {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function(element) {
+ return $A($(element).getElementsByTagName('*')).each(Element.extend);
+ },
+
+ firstDescendant: function(element) {
+ element = $(element).firstChild;
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ return $(element);
+ },
+
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
+ previousSiblings: function(element) {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function(element) {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function(element) {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function(element, selector) {
+ if (typeof selector == 'string')
+ selector = new Selector(selector);
+ return selector.match($(element));
+ },
+
+ up: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(element.parentNode);
+ var ancestors = element.ancestors();
+ return expression ? Selector.findElement(ancestors, expression, index) :
+ ancestors[index || 0];
+ },
+
+ down: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return element.firstDescendant();
+ var descendants = element.descendants();
+ return expression ? Selector.findElement(descendants, expression, index) :
+ descendants[index || 0];
+ },
+
+ previous: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+ var previousSiblings = element.previousSiblings();
+ return expression ? Selector.findElement(previousSiblings, expression, index) :
+ previousSiblings[index || 0];
+ },
+
+ next: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+ var nextSiblings = element.nextSiblings();
+ return expression ? Selector.findElement(nextSiblings, expression, index) :
+ nextSiblings[index || 0];
+ },
+
+ getElementsBySelector: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ getElementsByClassName: function(element, className) {
+ return document.getElementsByClassName(className, element);
+ },
+
+ readAttribute: function(element, name) {
+ element = $(element);
+ if (Prototype.Browser.IE) {
+ if (!element.attributes) return null;
+ var t = Element._attributeTranslations;
+ if (t.values[name]) return t.values[name](element, name);
+ if (t.names[name]) name = t.names[name];
+ var attribute = element.attributes[name];
+ return attribute ? attribute.nodeValue : null;
+ }
+ return element.getAttribute(name);
+ },
+
+ getHeight: function(element) {
+ return $(element).getDimensions().height;
+ },
+
+ getWidth: function(element) {
+ return $(element).getDimensions().width;
+ },
+
+ classNames: function(element) {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ var elementClassName = element.className;
+ if (elementClassName.length == 0) return false;
+ if (elementClassName == className ||
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ return true;
+ return false;
+ },
+
+ addClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element).add(className);
+ return element;
+ },
+
+ removeClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element).remove(className);
+ return element;
+ },
+
+ toggleClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+ return element;
+ },
+
+ observe: function() {
+ Event.observe.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ stopObserving: function() {
+ Event.stopObserving.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ element = $(element);
+ var node = element.firstChild;
+ while (node) {
+ var nextNode = node.nextSibling;
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ element.removeChild(node);
+ node = nextNode;
+ }
+ return element;
+ },
+
+ empty: function(element) {
+ return $(element).innerHTML.blank();
+ },
+
+ descendantOf: function(element, ancestor) {
+ element = $(element), ancestor = $(ancestor);
+ while (element = element.parentNode)
+ if (element == ancestor) return true;
+ return false;
+ },
+
+ scrollTo: function(element) {
+ element = $(element);
+ var pos = Position.cumulativeOffset(element);
+ window.scrollTo(pos[0], pos[1]);
+ return element;
+ },
+
+ getStyle: function(element, style) {
+ element = $(element);
+ style = style == 'float' ? 'cssFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css[style] : null;
+ }
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+ return value == 'auto' ? null : value;
+ },
+
+ getOpacity: function(element) {
+ return $(element).getStyle('opacity');
+ },
+
+ setStyle: function(element, styles, camelized) {
+ element = $(element);
+ var elementStyle = element.style;
+
+ for (var property in styles)
+ if (property == 'opacity') element.setOpacity(styles[property])
+ else
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
+ (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
+ (camelized ? property : property.camelize())] = styles[property];
+
+ return element;
+ },
+
+ setOpacity: function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
+ return element;
+ },
+
+ getDimensions: function(element) {
+ element = $(element);
+ var display = $(element).getStyle('display');
+ if (display != 'none' && display != null) // Safari bug
+ 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;
+ var originalDisplay = els.display;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = 'block';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = originalDisplay;
+ 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;
+ }
+ }
+ return element;
+ },
+
+ 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 = '';
+ }
+ return element;
+ },
+
+ makeClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return element;
+ element._overflow = element.style.overflow || 'auto';
+ if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+ element.style.overflow = 'hidden';
+ return element;
+ },
+
+ undoClipping: function(element) {
+ element = $(element);
+ if (!element._overflow) return element;
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+ element._overflow = null;
+ return element;
+ }
+};
+
+Object.extend(Element.Methods, {
+ childOf: Element.Methods.descendantOf,
+ childElements: Element.Methods.immediateDescendants
+});
+
+if (Prototype.Browser.Opera) {
+ Element.Methods._getStyle = Element.Methods.getStyle;
+ Element.Methods.getStyle = function(element, style) {
+ switch(style) {
+ case 'left':
+ case 'top':
+ case 'right':
+ case 'bottom':
+ if (Element._getStyle(element, 'position') == 'static') return null;
+ default: return Element._getStyle(element, style);
+ }
+ };
+}
+else if (Prototype.Browser.IE) {
+ Element.Methods.getStyle = function(element, style) {
+ element = $(element);
+ style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value && element.currentStyle) value = element.currentStyle[style];
+
+ if (style == 'opacity') {
+ if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if (value[1]) return parseFloat(value[1]) / 100;
+ return 1.0;
+ }
+
+ if (value == 'auto') {
+ if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+ return element['offset'+style.capitalize()] + 'px';
+ return null;
+ }
+ return value;
+ };
+
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ var filter = element.getStyle('filter'), style = element.style;
+ if (value == 1 || value === '') {
+ style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
+ return element;
+ } else if (value < 0.00001) value = 0;
+ style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
+ 'alpha(opacity=' + (value * 100) + ')';
+ return element;
+ };
+
+ // IE is missing .innerHTML support for TABLE-related elements
+ Element.Methods.update = function(element, html) {
+ element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
+ var tagName = element.tagName.toUpperCase();
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+ var div = document.createElement('div');
+ switch (tagName) {
+ case 'THEAD':
+ case 'TBODY':
+ div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
+ depth = 2;
+ break;
+ case 'TR':
+ div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
+ depth = 3;
+ break;
+ case 'TD':
+ div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
+ depth = 4;
+ }
+ $A(element.childNodes).each(function(node) { element.removeChild(node) });
+ depth.times(function() { div = div.firstChild });
+ $A(div.childNodes).each(function(node) { element.appendChild(node) });
+ } else {
+ element.innerHTML = html.stripScripts();
+ }
+ setTimeout(function() { html.evalScripts() }, 10);
+ return element;
+ }
+}
+else if (Prototype.Browser.Gecko) {
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1) ? 0.999999 :
+ (value === '') ? '' : (value < 0.00001) ? 0 : value;
+ return element;
+ };
+}
+
+Element._attributeTranslations = {
+ names: {
+ colspan: "colSpan",
+ rowspan: "rowSpan",
+ valign: "vAlign",
+ datetime: "dateTime",
+ accesskey: "accessKey",
+ tabindex: "tabIndex",
+ enctype: "encType",
+ maxlength: "maxLength",
+ readonly: "readOnly",
+ longdesc: "longDesc"
+ },
+ values: {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+ title: function(element) {
+ var node = element.getAttributeNode('title');
+ return node.specified ? node.nodeValue : null;
+ }
+ }
+};
+
+(function() {
+ Object.extend(this, {
+ href: this._getAttr,
+ src: this._getAttr,
+ type: this._getAttr,
+ disabled: this._flag,
+ checked: this._flag,
+ readonly: this._flag,
+ multiple: this._flag
+ });
+}).call(Element._attributeTranslations.values);
+
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ var t = Element._attributeTranslations, node;
+ attribute = t.names[attribute] || attribute;
+ node = $(element).getAttributeNode(attribute);
+ return node && node.specified;
+ }
+};
+
+Element.Methods.ByTag = {};
+
+Object.extend(Element, Element.Methods);
+
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+ document.createElement('div').__proto__) {
+ window.HTMLElement = {};
+ window.HTMLElement.prototype = document.createElement('div').__proto__;
+ Prototype.BrowserFeatures.ElementExtensions = true;
+}
+
+Element.hasAttribute = function(element, attribute) {
+ if (element.hasAttribute) return element.hasAttribute(attribute);
+ return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods) {
+ var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+ if (!methods) {
+ Object.extend(Form, Form.Methods);
+ Object.extend(Form.Element, Form.Element.Methods);
+ Object.extend(Element.Methods.ByTag, {
+ "FORM": Object.clone(Form.Methods),
+ "INPUT": Object.clone(Form.Element.Methods),
+ "SELECT": Object.clone(Form.Element.Methods),
+ "TEXTAREA": Object.clone(Form.Element.Methods)
+ });
+ }
+
+ if (arguments.length == 2) {
+ var tagName = methods;
+ methods = arguments[1];
+ }
+
+ if (!tagName) Object.extend(Element.Methods, methods || {});
+ else {
+ if (tagName.constructor == Array) tagName.each(extend);
+ else extend(tagName);
+ }
+
+ function extend(tagName) {
+ tagName = tagName.toUpperCase();
+ if (!Element.Methods.ByTag[tagName])
+ Element.Methods.ByTag[tagName] = {};
+ Object.extend(Element.Methods.ByTag[tagName], methods);
+ }
+
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
+ var cache = Element.extend.cache;
+ for (var property in methods) {
+ var value = methods[property];
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = cache.findOrStore(value);
+ }
+ }
+
+ function findDOMClass(tagName) {
+ var klass;
+ var trans = {
+ "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+ "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+ "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+ "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+ "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+ "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+ "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+ "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+ "FrameSet", "IFRAME": "IFrame"
+ };
+ if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName.capitalize() + 'Element';
+ if (window[klass]) return window[klass];
+
+ window[klass] = {};
+ window[klass].prototype = document.createElement(tagName).__proto__;
+ return window[klass];
+ }
+
+ if (F.ElementExtensions) {
+ copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ }
+
+ if (F.SpecificElementExtensions) {
+ for (var tag in Element.Methods.ByTag) {
+ var klass = findDOMClass(tag);
+ if (typeof klass == "undefined") continue;
+ copy(T[tag], klass.prototype);
+ }
+ }
+
+ Object.extend(Element, Element.Methods);
+ delete Element.ByTag;
+};
+
+var 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) {
+ var tagName = this.element.tagName.toUpperCase();
+ if (['TBODY', 'TR'].include(tagName)) {
+ 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($A(this).concat(classNameToAdd).join(' '));
+ },
+
+ remove: function(classNameToRemove) {
+ if (!this.include(classNameToRemove)) return;
+ this.set($A(this).without(classNameToRemove).join(' '));
+ },
+
+ toString: function() {
+ return $A(this).join(' ');
+ }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license. Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create();
+
+Selector.prototype = {
+ initialize: function(expression) {
+ this.expression = expression.strip();
+ this.compileMatcher();
+ },
+
+ compileMatcher: function() {
+ // Selectors with namespaced attributes can't use the XPath version
+ if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
+ return this.compileXPathMatcher();
+
+ var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+ c = Selector.criteria, le, p, m;
+
+ if (Selector._cache[e]) {
+ this.matcher = Selector._cache[e]; return;
+ }
+ this.matcher = ["this.matcher = function(root) {",
+ "var r = root, h = Selector.handlers, c = false, n;"];
+
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ p = ps[i];
+ if (m = e.match(p)) {
+ this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
+ new Template(c[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.matcher.push("return h.unique(n);\n}");
+ eval(this.matcher.join('\n'));
+ Selector._cache[this.expression] = this.matcher;
+ },
+
+ compileXPathMatcher: function() {
+ var e = this.expression, ps = Selector.patterns,
+ x = Selector.xpath, le, m;
+
+ if (Selector._cache[e]) {
+ this.xpath = Selector._cache[e]; return;
+ }
+
+ this.matcher = ['.//*'];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ if (m = e.match(ps[i])) {
+ this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
+ new Template(x[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.xpath = this.matcher.join('');
+ Selector._cache[this.expression] = this.xpath;
+ },
+
+ findElements: function(root) {
+ root = root || document;
+ if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+ return this.matcher(root);
+ },
+
+ match: function(element) {
+ return this.findElements(document).include(element);
+ },
+
+ toString: function() {
+ return this.expression;
+ },
+
+ inspect: function() {
+ return "#<Selector:" + this.expression.inspect() + ">";
+ }
+};
+
+Object.extend(Selector, {
+ _cache: {},
+
+ xpath: {
+ descendant: "//*",
+ child: "/*",
+ adjacent: "/following-sibling::*[1]",
+ laterSibling: '/following-sibling::*',
+ tagName: function(m) {
+ if (m[1] == '*') return '';
+ return "[local-name()='" + m[1].toLowerCase() +
+ "' or local-name()='" + m[1].toUpperCase() + "']";
+ },
+ className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+ id: "[@id='#{1}']",
+ attrPresence: "[@#{1}]",
+ attr: function(m) {
+ m[3] = m[5] || m[6];
+ return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+ },
+ pseudo: function(m) {
+ var h = Selector.xpath.pseudos[m[1]];
+ if (!h) return '';
+ if (typeof h === 'function') return h(m);
+ return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+ },
+ operators: {
+ '=': "[@#{1}='#{3}']",
+ '!=': "[@#{1}!='#{3}']",
+ '^=': "[starts-with(@#{1}, '#{3}')]",
+ '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+ '*=': "[contains(@#{1}, '#{3}')]",
+ '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+ '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+ },
+ pseudos: {
+ 'first-child': '[not(preceding-sibling::*)]',
+ 'last-child': '[not(following-sibling::*)]',
+ 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
+ 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
+ 'checked': "[@checked]",
+ 'disabled': "[@disabled]",
+ 'enabled': "[not(@disabled)]",
+ 'not': function(m) {
+ var e = m[6], p = Selector.patterns,
+ x = Selector.xpath, le, m, v;
+
+ var exclusion = [];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in p) {
+ if (m = e.match(p[i])) {
+ v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
+ exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+ return "[not(" + exclusion.join(" and ") + ")]";
+ },
+ 'nth-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+ },
+ 'nth-last-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+ },
+ 'nth-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("position() ", m);
+ },
+ 'nth-last-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+ },
+ 'first-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+ },
+ 'last-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+ },
+ 'only-of-type': function(m) {
+ var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+ },
+ nth: function(fragment, m) {
+ var mm, formula = m[6], predicate;
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ if (mm = formula.match(/^(\d+)$/)) // digit only
+ return '[' + fragment + "= " + mm[1] + ']';
+ if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (mm[1] == "-") mm[1] = -1;
+ var a = mm[1] ? Number(mm[1]) : 1;
+ var b = mm[2] ? Number(mm[2]) : 0;
+ predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+ "((#{fragment} - #{b}) div #{a} >= 0)]";
+ return new Template(predicate).evaluate({
+ fragment: fragment, a: a, b: b });
+ }
+ }
+ }
+ },
+
+ criteria: {
+ tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
+ className: 'n = h.className(n, r, "#{1}", c); c = false;',
+ id: 'n = h.id(n, r, "#{1}", c); c = false;',
+ attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
+ attr: function(m) {
+ m[3] = (m[5] || m[6]);
+ return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
+ },
+ pseudo: function(m) {
+ if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+ return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+ },
+ descendant: 'c = "descendant";',
+ child: 'c = "child";',
+ adjacent: 'c = "adjacent";',
+ laterSibling: 'c = "laterSibling";'
+ },
+
+ patterns: {
+ // combinators must be listed first
+ // (and descendant needs to be last combinator)
+ laterSibling: /^\s*~\s*/,
+ child: /^\s*>\s*/,
+ adjacent: /^\s*\+\s*/,
+ descendant: /^\s/,
+
+ // selectors follow
+ tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
+ id: /^#([\w\-\*]+)(\b|$)/,
+ className: /^\.([\w\-\*]+)(\b|$)/,
+ pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
+ attrPresence: /^\[([\w]+)\]/,
+ attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
+ },
+
+ handlers: {
+ // UTILITY FUNCTIONS
+ // joins two collections
+ concat: function(a, b) {
+ for (var i = 0, node; node = b[i]; i++)
+ a.push(node);
+ return a;
+ },
+
+ // marks an array of nodes for counting
+ mark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._counted = true;
+ return nodes;
+ },
+
+ unmark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._counted = undefined;
+ return nodes;
+ },
+
+ // mark each child node with its position (for nth calls)
+ // "ofType" flag indicates whether we're indexing for nth-of-type
+ // rather than nth-child
+ index: function(parentNode, reverse, ofType) {
+ parentNode._counted = true;
+ if (reverse) {
+ for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+ node = nodes[i];
+ if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+ }
+ } else {
+ for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+ if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+ }
+ },
+
+ // filters out duplicates and extends all nodes
+ unique: function(nodes) {
+ if (nodes.length == 0) return nodes;
+ var results = [], n;
+ for (var i = 0, l = nodes.length; i < l; i++)
+ if (!(n = nodes[i])._counted) {
+ n._counted = true;
+ results.push(Element.extend(n));
+ }
+ return Selector.handlers.unmark(results);
+ },
+
+ // COMBINATOR FUNCTIONS
+ descendant: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName('*'));
+ return results;
+ },
+
+ child: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
+ if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+ }
+ return results;
+ },
+
+ adjacent: function(nodes) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ var next = this.nextElementSibling(node);
+ if (next) results.push(next);
+ }
+ return results;
+ },
+
+ laterSibling: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, Element.nextSiblings(node));
+ return results;
+ },
+
+ nextElementSibling: function(node) {
+ while (node = node.nextSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ previousElementSibling: function(node) {
+ while (node = node.previousSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ // TOKEN FUNCTIONS
+ tagName: function(nodes, root, tagName, combinator) {
+ tagName = tagName.toUpperCase();
+ var results = [], h = Selector.handlers;
+ if (nodes) {
+ if (combinator) {
+ // fastlane for ordinary descendant combinators
+ if (combinator == "descendant") {
+ for (var i = 0, node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName(tagName));
+ return results;
+ } else nodes = this[combinator](nodes);
+ if (tagName == "*") return nodes;
+ }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.tagName.toUpperCase() == tagName) results.push(node);
+ return results;
+ } else return root.getElementsByTagName(tagName);
+ },
+
+ id: function(nodes, root, id, combinator) {
+ var targetNode = $(id), h = Selector.handlers;
+ if (!nodes && root == document) return targetNode ? [targetNode] : [];
+ if (nodes) {
+ if (combinator) {
+ if (combinator == 'child') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (targetNode.parentNode == node) return [targetNode];
+ } else if (combinator == 'descendant') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.descendantOf(targetNode, node)) return [targetNode];
+ } else if (combinator == 'adjacent') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Selector.handlers.previousElementSibling(targetNode) == node)
+ return [targetNode];
+ } else nodes = h[combinator](nodes);
+ }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node == targetNode) return [targetNode];
+ return [];
+ }
+ return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+ },
+
+ className: function(nodes, root, className, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ return Selector.handlers.byClassName(nodes, root, className);
+ },
+
+ byClassName: function(nodes, root, className) {
+ if (!nodes) nodes = Selector.handlers.descendant([root]);
+ var needle = ' ' + className + ' ';
+ for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+ nodeClassName = node.className;
+ if (nodeClassName.length == 0) continue;
+ if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+ results.push(node);
+ }
+ return results;
+ },
+
+ attrPresence: function(nodes, root, attr) {
+ var results = [];
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.hasAttribute(node, attr)) results.push(node);
+ return results;
+ },
+
+ attr: function(nodes, root, attr, value, operator) {
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ var handler = Selector.operators[operator], results = [];
+ for (var i = 0, node; node = nodes[i]; i++) {
+ var nodeValue = Element.readAttribute(node, attr);
+ if (nodeValue === null) continue;
+ if (handler(nodeValue, value)) results.push(node);
+ }
+ return results;
+ },
+
+ pseudo: function(nodes, name, value, root, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ return Selector.pseudos[name](nodes, value, root);
+ }
+ },
+
+ pseudos: {
+ 'first-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.previousElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'last-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.nextElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'only-child': function(nodes, value, root) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+ results.push(node);
+ return results;
+ },
+ 'nth-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root);
+ },
+ 'nth-last-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true);
+ },
+ 'nth-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, false, true);
+ },
+ 'nth-last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true, true);
+ },
+ 'first-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, false, true);
+ },
+ 'last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, true, true);
+ },
+ 'only-of-type': function(nodes, formula, root) {
+ var p = Selector.pseudos;
+ return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+ },
+
+ // handles the an+b logic
+ getIndices: function(a, b, total) {
+ if (a == 0) return b > 0 ? [b] : [];
+ return $R(1, total).inject([], function(memo, i) {
+ if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+ return memo;
+ });
+ },
+
+ // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+ nth: function(nodes, formula, root, reverse, ofType) {
+ if (nodes.length == 0) return [];
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ var h = Selector.handlers, results = [], indexed = [], m;
+ h.mark(nodes);
+ for (var i = 0, node; node = nodes[i]; i++) {
+ if (!node.parentNode._counted) {
+ h.index(node.parentNode, reverse, ofType);
+ indexed.push(node.parentNode);
+ }
+ }
+ if (formula.match(/^\d+$/)) { // just a number
+ formula = Number(formula);
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.nodeIndex == formula) results.push(node);
+ } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (m[1] == "-") m[1] = -1;
+ var a = m[1] ? Number(m[1]) : 1;
+ var b = m[2] ? Number(m[2]) : 0;
+ var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+ for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+ for (var j = 0; j < l; j++)
+ if (node.nodeIndex == indices[j]) results.push(node);
+ }
+ }
+ h.unmark(nodes);
+ h.unmark(indexed);
+ return results;
+ },
+
+ 'empty': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ // IE treats comments as element nodes
+ if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
+ results.push(node);
+ }
+ return results;
+ },
+
+ 'not': function(nodes, selector, root) {
+ var h = Selector.handlers, selectorType, m;
+ var exclusions = new Selector(selector).findElements(root);
+ h.mark(exclusions);
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node._counted) results.push(node);
+ h.unmark(exclusions);
+ return results;
+ },
+
+ 'enabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node.disabled) results.push(node);
+ return results;
+ },
+
+ 'disabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.disabled) results.push(node);
+ return results;
+ },
+
+ 'checked': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.checked) results.push(node);
+ return results;
+ }
+ },
+
+ operators: {
+ '=': function(nv, v) { return nv == v; },
+ '!=': function(nv, v) { return nv != v; },
+ '^=': function(nv, v) { return nv.startsWith(v); },
+ '$=': function(nv, v) { return nv.endsWith(v); },
+ '*=': function(nv, v) { return nv.include(v); },
+ '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+ '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
+ },
+
+ matchElements: function(elements, expression) {
+ var matches = new Selector(expression).findElements(), h = Selector.handlers;
+ h.mark(matches);
+ for (var i = 0, results = [], element; element = elements[i]; i++)
+ if (element._counted) results.push(element);
+ h.unmark(matches);
+ return results;
+ },
+
+ findElement: function(elements, expression, index) {
+ if (typeof expression == 'number') {
+ index = expression; expression = false;
+ }
+ return Selector.matchElements(elements, expression || '*')[index || 0];
+ },
+
+ findChildElements: function(element, expressions) {
+ var exprs = expressions.join(','), expressions = [];
+ exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+ expressions.push(m[1].strip());
+ });
+ var results = [], h = Selector.handlers;
+ for (var i = 0, l = expressions.length, selector; i < l; i++) {
+ selector = new Selector(expressions[i].strip());
+ h.concat(results, selector.findElements(element));
+ }
+ return (l > 1) ? h.unique(results) : results;
+ }
+});
+
+function $$() {
+ return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+ reset: function(form) {
+ $(form).reset();
+ return form;
+ },
+
+ serializeElements: function(elements, getHash) {
+ var data = elements.inject({}, function(result, element) {
+ if (!element.disabled && element.name) {
+ var key = element.name, value = $(element).getValue();
+ if (value != null) {
+ if (key in result) {
+ if (result[key].constructor != Array) result[key] = [result[key]];
+ result[key].push(value);
+ }
+ else result[key] = value;
+ }
+ }
+ return result;
+ });
+
+ return getHash ? data : Hash.toQueryString(data);
+ }
+};
+
+Form.Methods = {
+ serialize: function(form, getHash) {
+ return Form.serializeElements(Form.getElements(form), getHash);
+ },
+
+ getElements: function(form) {
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
+ },
+
+ getInputs: function(form, typeName, name) {
+ form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+ var input = inputs[i];
+ if ((typeName && input.type != typeName) || (name && input.name != name))
+ continue;
+ matchingInputs.push(Element.extend(input));
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function(form) {
+ form = $(form);
+ Form.getElements(form).invoke('disable');
+ return form;
+ },
+
+ enable: function(form) {
+ form = $(form);
+ Form.getElements(form).invoke('enable');
+ return form;
+ },
+
+ findFirstElement: function(form) {
+ return $(form).getElements().find(function(element) {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
+ focusFirstElement: function(form) {
+ form = $(form);
+ form.findFirstElement().activate();
+ return form;
+ },
+
+ request: function(form, options) {
+ form = $(form), options = Object.clone(options || {});
+
+ var params = options.parameters;
+ options.parameters = form.serialize(true);
+
+ if (params) {
+ if (typeof params == 'string') params = params.toQueryParams();
+ Object.extend(options.parameters, params);
+ }
+
+ if (form.hasAttribute('method') && !options.method)
+ options.method = form.method;
+
+ return new Ajax.Request(form.readAttribute('action'), options);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+ focus: function(element) {
+ $(element).focus();
+ return element;
+ },
+
+ select: function(element) {
+ $(element).select();
+ return element;
+ }
+}
+
+Form.Element.Methods = {
+ serialize: function(element) {
+ element = $(element);
+ if (!element.disabled && element.name) {
+ var value = element.getValue();
+ if (value != undefined) {
+ var pair = {};
+ pair[element.name] = value;
+ return Hash.toQueryString(pair);
+ }
+ }
+ return '';
+ },
+
+ getValue: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ return Form.Element.Serializers[method](element);
+ },
+
+ clear: function(element) {
+ $(element).value = '';
+ return element;
+ },
+
+ present: function(element) {
+ return $(element).value != '';
+ },
+
+ activate: function(element) {
+ element = $(element);
+ try {
+ element.focus();
+ if (element.select && (element.tagName.toLowerCase() != 'input' ||
+ !['button', 'reset', 'submit'].include(element.type)))
+ element.select();
+ } catch (e) {}
+ return element;
+ },
+
+ disable: function(element) {
+ element = $(element);
+ element.blur();
+ element.disabled = true;
+ return element;
+ },
+
+ enable: function(element) {
+ element = $(element);
+ element.disabled = false;
+ return element;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+ input: function(element) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element);
+ default:
+ return Form.Element.Serializers.textarea(element);
+ }
+ },
+
+ inputSelector: function(element) {
+ return element.checked ? element.value : null;
+ },
+
+ textarea: function(element) {
+ return element.value;
+ },
+
+ select: function(element) {
+ return this[element.type == 'select-one' ?
+ 'selectOne' : 'selectMany'](element);
+ },
+
+ selectOne: function(element) {
+ var index = element.selectedIndex;
+ return index >= 0 ? this.optionValue(element.options[index]) : null;
+ },
+
+ selectMany: function(element) {
+ var values, length = element.length;
+ if (!length) return null;
+
+ for (var i = 0, values = []; i < length; i++) {
+ var opt = element.options[i];
+ if (opt.selected) values.push(this.optionValue(opt));
+ }
+ return values;
+ },
+
+ optionValue: function(opt) {
+ // extend element because hasAttribute may not be native
+ return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+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();
+ var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+ ? this.lastValue != value : String(this.lastValue) != String(value));
+ if (changed) {
+ 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() {
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
+ },
+
+ registerCallback: function(element) {
+ if (element.type) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
+ break;
+ default:
+ 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,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
+
+ 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, length = Event.observers.length; i < length; i++) {
+ Event.stopObserving.apply(this, Event.observers[i]);
+ Event.observers[i][0] = null;
+ }
+ Event.observers = false;
+ },
+
+ observe: function(element, name, observer, useCapture) {
+ element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (Prototype.Browser.WebKit || element.attachEvent))
+ name = 'keydown';
+
+ Event._observeAndCache(element, name, observer, useCapture);
+ },
+
+ stopObserving: function(element, name, observer, useCapture) {
+ element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (Prototype.Browser.WebKit || element.attachEvent))
+ name = 'keydown';
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, observer, useCapture);
+ } else if (element.detachEvent) {
+ try {
+ element.detachEvent('on' + name, observer);
+ } catch (e) {}
+ }
+ }
+});
+
+/* prevent memory leaks in IE */
+if (Prototype.Browser.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) {
+ if(element.tagName=='BODY') break;
+ var 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;
+ },
+
+ 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 {
+ if (!window.opera || element.tagName=='BODY') {
+ 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 (Prototype.Browser.WebKit) {
+ 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];
+ }
+}
+
+Element.addMethods();
\ 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;
- }
-
-};
--- /dev/null
+/*
+Based on "Coffee with milk" table design by Roger Johansson, 456 Berea Street
+www.456bereastreet.com
+================================================*/
+
+.ricoLG_table {
+ border-top:1px solid #523A0B !important;
+ border-right:none;
+ font:normal 76%/150% "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
+ color:#000;
+}
+tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */
+ background:#EBE5D9 !important;
+ line-height:normal;
+ text-align:left;
+}
+
+tr.ricoLG_hdg th, tr.ricoLG_hdg td {
+ border-bottom:1px solid #523A0B;
+ background:#EBE5D9;
+ }
+
+tr.ricoLG_hdg th, tr.ricoLG_hdg td {
+ border-left: 1px solid #E0D8CD !important;
+}
+
+.ricoLG_bottom th, .ricoLG_bottom td {
+ border-left: 1px solid #FFF;
+}
+
+tr.ricoLG_hdg div.ricoLG_cell {
+ background:#EBE5D9;
+ font-weight:bold;
+ padding:0.5em 0 0.5em 0.5em;
+}
+div.ricoLG_outerDiv table a {
+ color:#523A0B;
+ text-decoration:none;
+ border-bottom:1px dotted;
+ }
+div.ricoLG_outerDiv tbody a:visited {
+ color:#444;
+ font-weight:normal;
+ }
+div.ricoLG_outerDiv table a:hover {
+ border-bottom-style:solid;
+ }
+
+.ricoLG_bottom div.ricoLG_oddRow {
+ background-color:#F7F4EE;
+ border-top: 1px solid #EBE5D9;
+ border-bottom: 1px solid #EBE5D9;
+}
+.ricoLG_bottom div.ricoLG_evenRow {
+ border-top: 1px solid #FFF;
+ border-bottom: 1px solid #FFF;
+}
+.ricoLG_selection {
+ background-color:#ffffee !important;
+ border-color:#523A0B !important;
+}
+.ricoLG_table {
+ border-style:none;
+}
+
+caption {
+ font-family:Georgia,Times,serif;
+ font-weight:normal;
+ font-size:1.4em;
+ text-align:left;
+ margin:0;
+ padding:0.5em 0.25em;
+ }
\ No newline at end of file
--- /dev/null
+/* -------------------------------------------------------
+Based on Grayed Out table design
+Author: Terence Ordona
+URL: http://www.imaputz.com/
+ ------------------------------------------------------- */
+div.ricoLG_outerDiv *, div.ricoLG_cell {
+ font-size: 11px;
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
+}
+
+.ricoLG_table {
+ border-top: 1px solid #CCC;
+ border-right: 1px solid #CCC;
+}
+
+tr.ricoLG_hdg th, tr.ricoLG_hdg td {
+ background-color: #FFF !important;
+ background: url(../images/grayedout.gif) #FFF repeat-x scroll center left;
+ border-bottom: 1px solid #CCC;
+}
+
+.ricoLG_table th, .ricoLG_table td {
+ border-left: 1px solid #CCC;
+}
+
+.ricoLG_bottom th, .ricoLG_bottom td {
+ border-bottom: 1px solid #CCC;
+}
+
+.ricoLG_bottom div.ricoLG_cell {
+ border-bottom: none;
+ padding: 5px;
+}
+
+tr.ricoLG_hdg .ricoLG_cell {
+ font-weight: normal;
+}
+
+div.ricoLG_outerDiv a:visited, div.ricoLG_outerDiv a:link {
+ color: #009;
+ text-decoration: none;
+}
+
+div.ricoLG_outerDiv a:hover {
+ color: #009;
+ text-decoration: underline;
+}
+
+.ricoLG_oddRow {
+ background-color: #EEE;
+}
+
+div.ricoLG_selection {
+ background-color: #999;
+ color: #FFF;
+}
+
+div.ricoLG_highlightDiv {
+ border-color: #999;
+}
+
+caption {
+ text-align: left;
+ font-size: 100%;
+ padding: .75em;
+ color: #000;
+}
+
--- /dev/null
+/* display grid headings with a green background */
+
+tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */
+ background-color : #cedebd !important;
+ color : #000000;
+ font-weight : bold;
+}
+div.ricoLG_selection { background-color: #cedebd; }
--- /dev/null
+tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */
+ Filter: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=white,endColorStr=Gainsboro);
+}
--- /dev/null
+/* ricoCalendar */
+
+div.ricoCalContainer, div.ricoTreeContainer {
+ position:absolute;
+ z-index:9999;
+ font-size:8pt;
+ left:0px;
+ top:0px;
+}
+
+table.ricoCalTab {
+ border:1px solid #666666;
+}
+
+table.ricoCalTab thead a {
+ border:1px solid #D4D0C8;
+ text-decoration: none;
+ color:black;
+}
+
+table.ricoCalTab thead img {
+ border:none;
+ padding-left: 0.3em;
+ padding-right: 0.3em;
+}
+
+table.ricoCalTab thead a:hover {
+ border:1px solid #666666;
+ cursor:pointer;
+}
+
+table.ricoCalTab thead td {
+ background-color: #D4D0C8;
+ font-weight: bold;
+ text-align:center;
+ padding: 2px;
+}
+
+table.ricoCalTab tfoot td {
+ color:#FFF;
+ text-align:center;
+ background-color: #666666;
+ padding: 2px;
+}
+
+table.ricoCalTab tfoot span {
+ text-decoration: underline;
+ cursor:pointer;
+}
+
+table.ricoCalTab tbody {
+ background-color: white;
+}
+
+tr.ricoCalDayNames td {
+ font-weight: bold;
+ padding: 0px 2px 0px 2px;
+ text-align:right;
+}
+
+td.ricoCal0, td.ricoCal1, td.ricoCal2, td.ricoCal3, td.ricoCal4, td.ricoCal5, td.ricoCal6, td.ricoCalToday, td.ricoCalEmpty {
+ text-decoration:none;
+ text-align:right;
+ width:3em;
+}
+
+/* Monday-Friday */
+td.ricoCal1, td.ricoCal2, td.ricoCal3, td.ricoCal4, td.ricoCal5 {
+ cursor:pointer;
+ color:black;
+}
+
+/* Sunday, Saturday */
+td.ricoCal0, td.ricoCal6 {
+ cursor:pointer;
+ color:#999;
+}
+
+td.ricoCalToday {
+ cursor:pointer;
+ color:red;
+ font-weight:bold;
+}
+
+td.ricoCalWeekNum {
+ background-color: #D4D0C8;
+ color:black;
+ text-align:center;
+}
+
+.ricoCalMenu {
+ position:absolute;
+ background-color: #FEE;
+ border-bottom:1px solid #666666;
+ border-right:1px solid #666666;
+}
+
+.ricoCalMenu td {
+ border-top:1px solid #666666;
+ border-left:1px solid #666666;
+}
+
+.ricoCalMenu a {
+ display:block;
+ text-decoration:none;
+ color:black;
+ cursor:pointer;
+}
+
+.ricoCalMenu a:hover {
+ background-color: #FCC;
+}
--- /dev/null
+div.ricoLG_outerDiv {
+ position:relative;
+ /*border:thin solid blue; /* for debugging */
+}
+
+div.ricoLG_innerDiv, div.ricoLG_frozenTabsDiv {
+ overflow:hidden;
+ margin:0px;
+ padding:0px;
+ position:absolute;
+ top:0px;
+}
+
+div.ricoLG_scrollDiv {
+ overflow:scroll;
+ position:relative;
+}
+
+div.ricoLG_scrollTabsDiv {
+ position:absolute;
+ top:0px;
+}
+
+div.ricoLG_resizeDiv {
+ position:absolute;
+ top:0px;
+ width:1px;
+ z-index:2;
+ background-color:blue;
+}
+
+div.ricoLG_highlightDiv {
+ position:absolute;
+ border: 2px solid black;
+}
+
+.ricoLG_table {
+ margin: 0px;
+ padding: 0px;
+ border-right: 1px solid silver;
+ border-top: 1px solid silver;
+}
+
+.ricoLG_table th, .ricoLG_table td {
+ border-left: 1px solid silver;
+}
+
+table.ricoLG_bottom {
+ border-top-style: none;
+}
+
+.ricoLG_evenRow { }
+.ricoLG_oddRow { background-color: #EEE; }
+.ricoLG_selection { background-color: #cedebd; }
+
+div.ricoLG_col {
+ overflow:hidden;
+ width:100px;
+}
+
+.ricoLG_top div.ricoLG_col {
+ position:relative;
+}
+
+.ricoLG_top div.ricoLG_Resize {
+ position:absolute;
+ width:5px;
+ height:100%;
+ top:0px;
+ cursor:e-resize;
+}
+
+.ricoLG_HdrIcon {
+ padding-left:2px;
+ padding-right:2px;
+}
+
+.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td {
+ border-bottom: 1px solid silver;
+}
+
+div.ricoLG_cell {
+ overflow:hidden;
+ height:1.2em;
+ padding-left: 3px;
+ margin: 0px;
+ font-size: 10pt;
+ padding-top:3px;
+ padding-bottom:3px;
+}
+
+div.ricoLG_messageDiv {
+ position:absolute;
+ z-index:200;
+ border:1px solid green;
+ background-color:white;
+ font-weight:bold;
+ font-size:larger;
+ color:navy;
+ text-align:center;
+ padding:4px;
+}
+
+p.ricoBookmark {
+ margin-bottom: 3px;
+ font-size: 10pt;
+}
+
+div.alignleft {
+ text-align: left;
+}
+
+div.aligncenter {
+ text-align: center;
+}
+
+div.alignright {
+ text-align: right;
+}
+
+span.ricoSessionTimer {
+ background-color:black;
+ color:white;
+}
+
--- /dev/null
+/* ricoLiveGridForms */
+
+span.ricoSaveMsg {
+ background-color:yellow;
+}
+
+span.ricoSessionTimer {
+ background-color:black;
+ color:white;
+}
+
+div.ricoLG_editDiv, div.ricoLG_editResponseDiv {
+ color:#000; background:#E8ECF3;
+ overflow:auto;
+ padding:8px;
+ border: 1px solid navy;
+ position:absolute;
+ font-size: 10pt;
+ z-index:300;
+ top:0px;
+ left:0px;
+}
+
+form .ricoEditLabel, form .ricoEditLabelWithHelp {
+ font-weight: bold;
+ text-align: left;
+ padding-right: 1em;
+}
+
+form .ricoEditLabelWithHelp {
+ color: navy;
+}
+
+form {
+ margin:0px;
+}
+
+.tabHeader {
+ height: 1.8em;
+ color : #AAA;
+ background: #D8E0F2;
+ font-weight : bold;
+ float: left;
+ display: inline;
+ margin-left: 2px;
+ margin-right: 2px;
+ text-align: center;
+ white-space:nowrap;
+ overflow:hidden;
+}
+
+.tabHover {
+ color : #666;
+ cursor: pointer;
+}
+
+.tabSelected {
+ color : #444;
+ background: #CFD4E6;
+ cursor: auto;
+}
+
+.tabContentContainer {
+ clear:both;
+}
+
+div.ricoLG_editDiv .tabContent, div.ricoLG_editDiv .noTabContent {
+ color:#000; background:#CFD4E6;
+ overflow: hidden;
+ padding: 4px;
+ white-space:nowrap;
+}
+
+div.ricoLG_editDiv .noTabContent {
+ float:left; /* required by IE7 */
+}
+
+span.ricoLookup {
+ display:none;
+}
+
--- /dev/null
+/* ricoMenu */
+
+div.ricoMenu, div.ricoMenuSafari {
+position: absolute;
+z-index: 100;
+border:1px solid #666;
+padding:2px;
+cursor:default;
+visibility: hidden;
+}
+
+div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu a {
+background-color:menu;
+color: menutext;
+text-decoration: none;
+font-family:tahoma,arial,helvetica,sans-serif;
+font-size: 8pt;
+display:block;
+}
+
+div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari a {
+background-color:#EDEDED;
+text-decoration: none;
+font-family:tahoma,arial,helvetica,sans-serif;
+font-size: 8pt;
+display:block;
+}
+
+div.ricoMenu div.ricoMenuHeading{
+padding: 1px 0px;
+font-weight:bold;
+}
+
+div.ricoMenuSafari div.ricoMenuHeading{
+padding: 1px 0px;
+color: black;
+display: block;
+font-weight:bold;
+}
+
+div.ricoMenu .enabled {
+position: relative;
+}
+
+div.ricoMenuSafari .enabled {
+color: black;
+}
+
+div.ricoMenu .enabled, div.ricoMenu .enabled-hover, div.ricoMenuSafari .enabled, div.ricoMenuSafari .enabled-hover, div.ricoMenu .disabled, div.ricoMenuSafari .disabled {
+padding-left: 1em;
+padding-top:0.1em;
+padding-bottom:0.1em;
+z-index: 101;
+}
+
+div.ricoMenu .disabled, div.ricoMenuSafari .disabled {
+color: #999;
+}
+
+div.ricoMenu hr{
+height:1px;
+margin:1px;
+border:0;
+color: menu;
+background-color: menu;
+}
+
+div.ricoMenu .enabled-hover, div.ricoMenu .ricoSubMenuOpen {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+div.ricoMenuSafari .enabled-hover, div.ricoMenuSafari .ricoSubMenuOpen {
+ background-color: #1657B8;
+ color: white;
+}
+
+div.ricoMenu .ricoSubMenu, div.ricoMenu .ricoSubMenuOpen, div.ricoMenuSafari .ricoSubMenu, div.ricoMenuSafari .ricoSubMenuOpen {
+padding: 1px 0px;
+display: block;
+font-weight:bold;
+z-index: 101;
+position: relative;
+}
+
+div.ricoMenu div.ricoMenuBreak, div.ricoMenuSafari div.ricoMenuBreak {
+height:1px;
+margin:3px 0 3px 0;
+padding:0;
+background-color: #AAA;
+width:100%;
+line-height:5px;
+overflow:hidden;
+}
+
--- /dev/null
+/* ricoTree */
+
+div.ricoTreeContainer {
+ background-color:#cedebd;
+ padding:4px;
+ border:1px solid black;
+ top:0px;
+ left:0px;
+ position:absolute;
+ z-index:9999;
+}
+
+div.ricoTree {
+ border:thin inset;
+ overflow:auto;
+ background-color:#FFF;
+}
+
+div.ricoTree p, div.ricoTree a {
+ margin:0px;
+ padding-left:0.3em;
+ white-space:nowrap;
+}
+
+div.ricoTree a {
+ cursor:pointer;
+ text-decoration:none;
+}
+
+div.ricoTree a:hover {
+ background-color:#EEE;
+}
+
+div.ricoTree img {
+ margin:0px;
+ padding:0px;
+ display:block;
+}
+
+div.ricoTree * {
+ font-size:8pt;
+}
--- /dev/null
+tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */
+ background-color:#e0e0c0 !important;
+ vertical-align:middle;
+}
+
+tr.ricoLG_hdg div.ricoLG_cell {
+ border-top: 1px solid #F0F0E8;
+}
+
+.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td {
+ border-bottom: 1px solid #D8d0c0;;
+}
+
+.ricoLG_table th, .ricoLG_table td {
+ border-left: 1px solid #F0F0E8;
+ border-right: 1px solid #D8d0c0;
+}
+
+div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu .ricoSubMenu, div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari .ricoSubMenu {
+ background-color:#f0f0e0;
+}
+
+div.ricoMenu, div.ricoMenu div.ricoMenuHeading, div.ricoMenu .ricoSubMenu, div.ricoMenu .ricoSubMenuOpen, div.ricoMenuSafari, div.ricoMenuSafari div.ricoMenuHeading, div.ricoMenuSafari .ricoSubMenu, div.ricoMenuSafari .ricoSubMenuOpen {
+ border-top: 1px solid #F0F0E8;
+ border-left: 1px solid #F0F0E8;
+ border-bottom: 1px solid #D8d0c0;;
+ border-right: 1px solid #D8d0c0;
+}
+
+.ricoLG_table {
+ border-style:none;
+}
+
+div.ricoLG_selection {
+ background-color:#e0e0c0;
+}
--- /dev/null
+/* -------------------------------------------------------
+Based on warm fall table design
+Author: Mya Leigh
+Theme: A Warm, Fall Table - Easy to Read
+URL: http://www.myaleigh.com
+ ------------------------------------------------------- */
+.ricoLG_table {
+ border-top: 1px solid #84785e;
+ border-right: 1px solid #84785e;
+}
+
+tr.ricoLG_hdg .ricoLG_cell, tr.ricoLG_hdg th, tr.ricoLG_hdg td { /* td/th required for IE */
+ background-color: #a24116 !important;
+ color: #ffffff !important;
+}
+
+.ricoLG_table th, .ricoLG_table td {
+ border-left: 1px solid #84785e;
+}
+
+.ricoLG_bottom div.ricoLG_cell, .ricoLG_top th, .ricoLG_top td {
+ border-bottom: 1px solid #84785e;
+}
+
+tr.ricoLG_hdg .ricoLG_cell {
+ background-color: #a24116;
+ border: 0;
+ color: #ffffff;
+ padding: .75em;
+ font: "Verdana", Arial, Helvetica, sans-serif;
+ font-weight: bold;
+}
+
+div.ricoLG_outerDiv a:visited, div.ricoLG_outerDiv a:link, div.ricoLG_outerDiv a:active {
+ color: #101011;
+ text-decoration: none;
+}
+
+div.ricoLG_outerDiv a:hover {
+ text-decoration: underline;
+}
+
+div.ricoLG_outerDiv tbody a:visited {
+ color:#444;
+}
+
+.ricoLG_oddRow {
+ background-color: #fffce1;
+ color: #101011;
+}
+
+.ricoLG_selection {
+ background-color: #a24116;
+ color: #ffffff;
+}
+
+caption {
+ text-align: left;
+ font-size: 100%;
+ padding: .75em;
+ color: #000;
+}
+
--- /dev/null
+<html>
+<head>
+<title>Export</title>
+<SCRIPT TYPE="text/javascript">
+function getdata() {
+ if (!window.opener || window.opener.closed) {
+ alert('Error! Parent window is closed');
+ return;
+ }
+ var divID=window.location.search;
+ if (divID.length<2) {
+ alert('Error! Invalid id');
+ return;
+ }
+ divID=divID.substring(1);
+ var oDiv=window.opener.document.getElementById(divID);
+ if (!oDiv) {
+ alert('Error! Can not find \"'+divID+'\"');
+ return;
+ }
+ var oSS=document.getElementById('ss')
+ if (!oSS) {
+ alert('Error! Can not find spreadsheet');
+ return;
+ }
+ oSS.HTMLData=oDiv.innerHTML;
+}
+window.onload=getdata;
+</SCRIPT>
+</head>
+<body>
+<object id="ss" classid="CLSID:0002E559-0000-0000-C000-000000000046" style="width:100%;height:100%"></object>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+<title>Export</title>
+<SCRIPT TYPE="text/javascript">
+function getdata() {
+ if (!window.opener || window.opener.closed) {
+ alert('Error! Parent window is closed');
+ return;
+ }
+ var divID=window.location.search;
+ if (divID.length<2) {
+ alert('Error! Invalid id');
+ return;
+ }
+ divID=divID.substring(1);
+ var oDiv=window.opener.document.getElementById(divID);
+ if (!oDiv) {
+ alert('Error! Can not find \"'+divID+'\"');
+ return;
+ }
+ document.body.innerHTML=oDiv.innerHTML;
+}
+window.onload=getdata;
+</SCRIPT>
+</head>
+<body>
+</body>
+</html>
--- /dev/null
+/* Prototype JavaScript framework, version 1.5.1_rc3
+ * (c) 2005-2007 Sam Stephenson
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.5.1_rc3',
+
+ Browser: {
+ IE: !!(window.attachEvent && !window.opera),
+ Opera: !!window.opera,
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
+ },
+
+ BrowserFeatures: {
+ XPath: !!document.evaluate,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ (document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__)
+ },
+
+ ScriptFragment: '<script[^>]*>([\u0001-\uFFFF]*?)</script>',
+ JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,
+
+ 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 (var property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+Object.extend(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;
+ }
+ },
+
+ toJSON: function(object) {
+ var type = typeof object;
+ switch(type) {
+ case 'undefined':
+ case 'function':
+ case 'unknown': return;
+ case 'boolean': return object.toString();
+ }
+ if (object === null) return 'null';
+ if (object.toJSON) return object.toJSON();
+ if (object.ownerDocument === document) return;
+ var results = [];
+ for (var property in object) {
+ var value = Object.toJSON(object[property]);
+ if (value !== undefined)
+ results.push(property.toJSON() + ': ' + value);
+ }
+ return '{' + results.join(', ') + '}';
+ },
+
+ keys: function(object) {
+ var keys = [];
+ for (var property in object)
+ keys.push(property);
+ return keys;
+ },
+
+ values: function(object) {
+ var values = [];
+ for (var property in object)
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function(object) {
+ return Object.extend({}, object);
+ }
+});
+
+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, args = $A(arguments), object = args.shift();
+ return function(event) {
+ return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
+ }
+}
+
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ return this.toPaddedString(2, 16);
+ },
+
+ succ: function() {
+ return this + 1;
+ },
+
+ times: function(iterator) {
+ $R(0, this, true).each(iterator);
+ return this;
+ },
+
+ toPaddedString: function(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ },
+
+ toJSON: function() {
+ return isFinite(this) ? this.toString() : 'null';
+ }
+});
+
+Date.prototype.toJSON = function() {
+ return '"' + this.getFullYear() + '-' +
+ (this.getMonth() + 1).toPaddedString(2) + '-' +
+ this.getDate().toPaddedString(2) + 'T' +
+ this.getHours().toPaddedString(2) + ':' +
+ this.getMinutes().toPaddedString(2) + ':' +
+ this.getSeconds().toPaddedString(2) + '"';
+};
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0, length = arguments.length; i < 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() {
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ stop: function() {
+ if (!this.timer) return;
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.callback(this);
+ } finally {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+}
+Object.extend(String, {
+ interpret: function(value) {
+ return value == null ? '' : String(value);
+ },
+ specialChar: {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '\\': '\\\\'
+ }
+});
+
+Object.extend(String.prototype, {
+ gsub: function(pattern, replacement) {
+ var result = '', source = this, match;
+ replacement = arguments.callee.prepareReplacement(replacement);
+
+ while (source.length > 0) {
+ if (match = source.match(pattern)) {
+ result += source.slice(0, match.index);
+ result += String.interpret(replacement(match));
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source, source = '';
+ }
+ }
+ return result;
+ },
+
+ sub: function(pattern, replacement, count) {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = count === undefined ? 1 : count;
+
+ return this.gsub(pattern, function(match) {
+ if (--count < 0) return match[0];
+ return replacement(match);
+ });
+ },
+
+ scan: function(pattern, iterator) {
+ this.gsub(pattern, iterator);
+ return this;
+ },
+
+ truncate: function(length, truncation) {
+ length = length || 30;
+ truncation = truncation === undefined ? '...' : truncation;
+ return this.length > length ?
+ this.slice(0, length - truncation.length) + truncation : this;
+ },
+
+ strip: function() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
+
+ 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(function(script) { return eval(script) });
+ },
+
+ escapeHTML: function() {
+ var self = arguments.callee;
+ self.text.data = this;
+ return self.div.innerHTML;
+ },
+
+ unescapeHTML: function() {
+ var div = document.createElement('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0] ? (div.childNodes.length > 1 ?
+ $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
+ div.childNodes[0].nodeValue) : '';
+ },
+
+ toQueryParams: function(separator) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return {};
+
+ return match[1].split(separator || '&').inject({}, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var key = decodeURIComponent(pair.shift());
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
+ if (value != undefined) value = decodeURIComponent(value);
+
+ if (key in hash) {
+ if (hash[key].constructor != Array) hash[key] = [hash[key]];
+ hash[key].push(value);
+ }
+ else hash[key] = value;
+ }
+ return hash;
+ });
+ },
+
+ toArray: function() {
+ return this.split('');
+ },
+
+ succ: function() {
+ return this.slice(0, this.length - 1) +
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+ },
+
+ times: function(count) {
+ var result = '';
+ for (var i = 0; i < count; i++) result += this;
+ return result;
+ },
+
+ camelize: function() {
+ var parts = this.split('-'), len = parts.length;
+ if (len == 1) return parts[0];
+
+ var camelized = this.charAt(0) == '-'
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+ : parts[0];
+
+ for (var i = 1; i < len; i++)
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+ return camelized;
+ },
+
+ capitalize: function() {
+ return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
+ },
+
+ underscore: function() {
+ return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
+ },
+
+ dasherize: function() {
+ return this.gsub(/_/,'-');
+ },
+
+ inspect: function(useDoubleQuotes) {
+ var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
+ var character = String.specialChar[match[0]];
+ return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
+ });
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ },
+
+ toJSON: function() {
+ return this.inspect(true);
+ },
+
+ unfilterJSON: function(filter) {
+ return this.sub(filter || Prototype.JSONFilter, '#{1}');
+ },
+
+ evalJSON: function(sanitize) {
+ var json = this.unfilterJSON();
+ try {
+ if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
+ return eval('(' + json + ')');
+ } catch (e) { }
+ throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
+ },
+
+ include: function(pattern) {
+ return this.indexOf(pattern) > -1;
+ },
+
+ startsWith: function(pattern) {
+ return this.indexOf(pattern) === 0;
+ },
+
+ endsWith: function(pattern) {
+ var d = this.length - pattern.length;
+ return d >= 0 && this.lastIndexOf(pattern) === d;
+ },
+
+ empty: function() {
+ return this == '';
+ },
+
+ blank: function() {
+ return /^\s*$/.test(this);
+ }
+});
+
+if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
+ escapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ },
+ unescapeHTML: function() {
+ return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+ if (typeof replacement == 'function') return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+Object.extend(String.prototype.escapeHTML, {
+ div: document.createElement('div'),
+ text: document.createTextNode('')
+});
+
+with (String.prototype.escapeHTML) div.appendChild(text);
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+ initialize: function(template, pattern) {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function(object) {
+ return this.template.gsub(this.pattern, function(match) {
+ var before = match[1];
+ if (before == '\\') return match[2];
+ return before + String.interpret(object[match[3]]);
+ });
+ }
+}
+
+var $break = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+ each: function(iterator) {
+ var index = 0;
+ try {
+ this._each(function(value) {
+ iterator(value, index++);
+ });
+ } catch (e) {
+ if (e != $break) throw e;
+ }
+ return this;
+ },
+
+ eachSlice: function(number, iterator) {
+ var index = -number, slices = [], array = this.toArray();
+ while ((index += number) < array.length)
+ slices.push(array.slice(index, index+number));
+ return slices.map(iterator);
+ },
+
+ 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 = false;
+ 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 || Prototype.K)(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;
+ },
+
+ inGroupsOf: function(number, fillWith) {
+ fillWith = fillWith === undefined ? null : fillWith;
+ return this.eachSlice(number, function(slice) {
+ while(slice.length < number) slice.push(fillWith);
+ return slice;
+ });
+ },
+
+ 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.map(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 (result == undefined || value >= result)
+ result = value;
+ });
+ return result;
+ },
+
+ min: function(iterator) {
+ var result;
+ this.each(function(value, index) {
+ value = (iterator || Prototype.K)(value, index);
+ if (result == undefined || value < result)
+ 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.map(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.map();
+ },
+
+ 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) {
+ return iterator(collections.pluck(index));
+ });
+ },
+
+ size: function() {
+ return this.toArray().length;
+ },
+
+ 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, length = iterable.length; i < length; i++)
+ results.push(iterable[i]);
+ return results;
+ }
+}
+
+if (Prototype.Browser.WebKit) {
+ $A = Array.from = function(iterable) {
+ if (!iterable) return [];
+ if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
+ iterable.toArray) {
+ return iterable.toArray();
+ } else {
+ var results = [];
+ for (var i = 0, length = iterable.length; i < length; i++)
+ results.push(iterable[i]);
+ return results;
+ }
+ }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+ Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+ _each: function(iterator) {
+ for (var i = 0, length = this.length; i < 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 != null;
+ });
+ },
+
+ flatten: function() {
+ return this.inject([], function(array, value) {
+ return array.concat(value && 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, length = this.length; i < length; i++)
+ if (this[i] == object) return i;
+ return -1;
+ },
+
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ reduce: function() {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function(sorted) {
+ return this.inject([], function(array, value, index) {
+ if (0 == index || (sorted ? array.last() != value : !array.include(value)))
+ array.push(value);
+ return array;
+ });
+ },
+
+ clone: function() {
+ return [].concat(this);
+ },
+
+ size: function() {
+ return this.length;
+ },
+
+ inspect: function() {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ },
+
+ toJSON: function() {
+ var results = [];
+ this.each(function(object) {
+ var value = Object.toJSON(object);
+ if (value !== undefined) results.push(value);
+ });
+ return '[' + results.join(', ') + ']';
+ }
+});
+
+Array.prototype.toArray = Array.prototype.clone;
+
+function $w(string) {
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera){
+ Array.prototype.concat = function() {
+ var array = [];
+ for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ for (var i = 0, length = arguments.length; i < length; i++) {
+ if (arguments[i].constructor == Array) {
+ for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
+ array.push(arguments[i][j]);
+ } else {
+ array.push(arguments[i]);
+ }
+ }
+ return array;
+ }
+}
+var Hash = function(object) {
+ if (object instanceof Hash) this.merge(object);
+ else Object.extend(this, object || {});
+};
+
+Object.extend(Hash, {
+ toQueryString: function(obj) {
+ var parts = [];
+ parts.add = arguments.callee.addPair;
+
+ this.prototype._each.call(obj, function(pair) {
+ if (!pair.key) return;
+ var value = pair.value;
+
+ if (value && typeof value == 'object') {
+ if (value.constructor == Array) value.each(function(value) {
+ parts.add(pair.key, value);
+ });
+ return;
+ }
+ parts.add(pair.key, value);
+ });
+
+ return parts.join('&');
+ },
+
+ toJSON: function(object) {
+ var results = [];
+ this.prototype._each.call(object, function(pair) {
+ var value = Object.toJSON(pair.value);
+ if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
+ });
+ return '{' + results.join(', ') + '}';
+ }
+});
+
+Hash.toQueryString.addPair = function(key, value, prefix) {
+ key = encodeURIComponent(key);
+ if (value === undefined) this.push(key);
+ else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
+}
+
+Object.extend(Hash.prototype, Enumerable);
+Object.extend(Hash.prototype, {
+ _each: function(iterator) {
+ for (var key in this) {
+ var value = this[key];
+ if (value && value == Hash.prototype[key]) 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(this, function(mergedHash, pair) {
+ mergedHash[pair.key] = pair.value;
+ return mergedHash;
+ });
+ },
+
+ remove: function() {
+ var result;
+ for(var i = 0, length = arguments.length; i < length; i++) {
+ var value = this[arguments[i]];
+ if (value !== undefined){
+ if (result === undefined) result = value;
+ else {
+ if (result.constructor != Array) result = [result];
+ result.push(value)
+ }
+ }
+ delete this[arguments[i]];
+ }
+ return result;
+ },
+
+ toQueryString: function() {
+ return Hash.toQueryString(this);
+ },
+
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ },
+
+ toJSON: function() {
+ return Hash.toJSON(this);
+ }
+});
+
+function $H(object) {
+ if (object instanceof Hash) return object;
+ return new Hash(object);
+};
+
+// Safari iterates over shadowed properties
+if (function() {
+ var i = 0, Test = function(value) { this.key = value };
+ Test.prototype.key = 'foo';
+ for (var property in new Test('bar')) i++;
+ return i > 1;
+}()) Hash.prototype._each = function(iterator) {
+ var cache = [];
+ for (var key in this) {
+ var value = this[key];
+ if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
+ cache.push(key);
+ var pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+};
+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;
+ while (this.include(value)) {
+ iterator(value);
+ value = value.succ();
+ }
+ },
+
+ 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 XMLHttpRequest()},
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+ ) || false;
+ },
+
+ activeRequestCount: 0
+}
+
+Ajax.Responders = {
+ responders: [],
+
+ _each: function(iterator) {
+ this.responders._each(iterator);
+ },
+
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
+ },
+
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
+ },
+
+ dispatch: function(callback, request, transport, json) {
+ this.each(function(responder) {
+ if (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,
+ contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
+ parameters: ''
+ }
+ Object.extend(this.options, options || {});
+
+ this.options.method = this.options.method.toLowerCase();
+ if (typeof this.options.parameters == 'string')
+ this.options.parameters = this.options.parameters.toQueryParams();
+ }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ _complete: false,
+
+ initialize: function(url, options) {
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+ this.request(url);
+ },
+
+ request: function(url) {
+ this.url = url;
+ this.method = this.options.method;
+ var params = Object.clone(this.options.parameters);
+
+ if (!['get', 'post'].include(this.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.method;
+ this.method = 'post';
+ }
+
+ this.parameters = params;
+
+ if (params = Hash.toQueryString(params)) {
+ // when GET, append parameters to URL
+ if (this.method == 'get')
+ this.url += (this.url.include('?') ? '&' : '?') + params;
+ else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ params += '&_=';
+ }
+
+ try {
+ if (this.options.onCreate) this.options.onCreate(this.transport);
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+ this.transport.open(this.method.toUpperCase(), this.url,
+ this.options.asynchronous);
+
+ if (this.options.asynchronous)
+ setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
+
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ this.setRequestHeaders();
+
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+ this.transport.send(this.body);
+
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
+ this.onStateChange();
+
+ }
+ catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1 && !((readyState == 4) && this._complete))
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ setRequestHeaders: function() {
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
+
+ if (this.method == 'post') {
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
+ }
+
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
+
+ if (typeof extras.push == 'function')
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
+
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
+ },
+
+ success: function() {
+ return !this.transport.status
+ || (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ respondToReadyState: function(readyState) {
+ var state = Ajax.Request.Events[readyState];
+ var transport = this.transport, json = this.evalJSON();
+
+ if (state == 'Complete') {
+ try {
+ this._complete = true;
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ var contentType = this.getHeader('Content-type');
+ if (contentType && contentType.strip().
+ match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + state, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if (state == 'Complete') {
+ // avoid memory leak in MSIE: clean up
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ getHeader: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) { return null }
+ },
+
+ evalJSON: function() {
+ try {
+ var json = this.getHeader('X-JSON');
+ return json ? json.evalJSON() : null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval((this.transport.responseText || '').unfilterJSON());
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ 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.container = {
+ success: (container.success || 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, param) {
+ this.updateContent();
+ onComplete(transport, param);
+ }).bind(this);
+
+ this.request(url);
+ },
+
+ updateContent: function() {
+ var receiver = this.container[this.success() ? 'success' : 'failure'];
+ var response = this.transport.responseText;
+
+ if (!this.options.evalScripts) response = response.stripScripts();
+
+ if (receiver = $(receiver)) {
+ if (this.options.insertion)
+ new this.options.insertion(receiver, response);
+ else
+ receiver.update(response);
+ }
+
+ if (this.success()) {
+ 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.options.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);
+ }
+});
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
+ }
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+ document._getElementsByXPath = function(expression, parentElement) {
+ var results = [];
+ var query = document.evaluate(expression, $(parentElement) || document,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
+ results.push(query.snapshotItem(i));
+ return results;
+ };
+
+ document.getElementsByClassName = function(className, parentElement) {
+ var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+ return document._getElementsByXPath(q, parentElement);
+ }
+
+} else document.getElementsByClassName = function(className, parentElement) {
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ var elements = [], child;
+ for (var i = 0, length = children.length; i < length; i++) {
+ child = children[i];
+ if (Element.hasClassName(child, className))
+ elements.push(Element.extend(child));
+ }
+ return elements;
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element) var Element = {};
+
+Element.extend = function(element) {
+ var F = Prototype.BrowserFeatures;
+ if (!element || !element.tagName || element.nodeType == 3 ||
+ element._extended || F.SpecificElementExtensions || element == window)
+ return element;
+
+ var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
+ T = Element.Methods.ByTag;
+
+ // extend methods for all tags (Safari doesn't need this)
+ if (!F.ElementExtensions) {
+ Object.extend(methods, Element.Methods),
+ Object.extend(methods, Element.Methods.Simulated);
+ }
+
+ // extend methods for specific tags
+ if (T[tagName]) Object.extend(methods, T[tagName]);
+
+ for (var property in methods) {
+ var value = methods[property];
+ if (typeof value == 'function' && !(property in element))
+ element[property] = cache.findOrStore(value);
+ }
+
+ element._extended = Prototype.emptyFunction;
+ return element;
+};
+
+Element.extend.cache = {
+ findOrStore: function(value) {
+ return this[value] = this[value] || function() {
+ return value.apply(null, [this].concat($A(arguments)));
+ }
+ }
+};
+
+Element.Methods = {
+ visible: function(element) {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function(element) {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
+ },
+
+ hide: function(element) {
+ $(element).style.display = 'none';
+ return element;
+ },
+
+ show: function(element) {
+ $(element).style.display = '';
+ return element;
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ return element;
+ },
+
+ update: function(element, html) {
+ html = typeof html == 'undefined' ? '' : html.toString();
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ },
+
+ replace: function(element, html) {
+ element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
+ if (element.outerHTML) {
+ element.outerHTML = html.stripScripts();
+ } else {
+ var range = element.ownerDocument.createRange();
+ range.selectNodeContents(element);
+ element.parentNode.replaceChild(
+ range.createContextualFragment(html.stripScripts()), element);
+ }
+ setTimeout(function() {html.evalScripts()}, 10);
+ return element;
+ },
+
+ inspect: function(element) {
+ element = $(element);
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
+ },
+
+ recursivelyCollect: function(element, property) {
+ element = $(element);
+ var elements = [];
+ while (element = element[property])
+ if (element.nodeType == 1)
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function(element) {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function(element) {
+ return $A($(element).getElementsByTagName('*')).each(Element.extend);
+ },
+
+ firstDescendant: function(element) {
+ element = $(element).firstChild;
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ return $(element);
+ },
+
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
+ previousSiblings: function(element) {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function(element) {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function(element) {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function(element, selector) {
+ if (typeof selector == 'string')
+ selector = new Selector(selector);
+ return selector.match($(element));
+ },
+
+ up: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(element.parentNode);
+ var ancestors = element.ancestors();
+ return expression ? Selector.findElement(ancestors, expression, index) :
+ ancestors[index || 0];
+ },
+
+ down: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return element.firstDescendant();
+ var descendants = element.descendants();
+ return expression ? Selector.findElement(descendants, expression, index) :
+ descendants[index || 0];
+ },
+
+ previous: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+ var previousSiblings = element.previousSiblings();
+ return expression ? Selector.findElement(previousSiblings, expression, index) :
+ previousSiblings[index || 0];
+ },
+
+ next: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+ var nextSiblings = element.nextSiblings();
+ return expression ? Selector.findElement(nextSiblings, expression, index) :
+ nextSiblings[index || 0];
+ },
+
+ getElementsBySelector: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ getElementsByClassName: function(element, className) {
+ return document.getElementsByClassName(className, element);
+ },
+
+ readAttribute: function(element, name) {
+ element = $(element);
+ if (Prototype.Browser.IE) {
+ if (!element.attributes) return null;
+ var t = Element._attributeTranslations;
+ if (t.values[name]) return t.values[name](element, name);
+ if (t.names[name]) name = t.names[name];
+ var attribute = element.attributes[name];
+ return attribute ? attribute.nodeValue : null;
+ }
+ return element.getAttribute(name);
+ },
+
+ getHeight: function(element) {
+ return $(element).getDimensions().height;
+ },
+
+ getWidth: function(element) {
+ return $(element).getDimensions().width;
+ },
+
+ classNames: function(element) {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ var elementClassName = element.className;
+ if (elementClassName.length == 0) return false;
+ if (elementClassName == className ||
+ elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ return true;
+ return false;
+ },
+
+ addClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element).add(className);
+ return element;
+ },
+
+ removeClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element).remove(className);
+ return element;
+ },
+
+ toggleClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
+ return element;
+ },
+
+ observe: function() {
+ Event.observe.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ stopObserving: function() {
+ Event.stopObserving.apply(Event, arguments);
+ return $A(arguments).first();
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ element = $(element);
+ var node = element.firstChild;
+ while (node) {
+ var nextNode = node.nextSibling;
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ element.removeChild(node);
+ node = nextNode;
+ }
+ return element;
+ },
+
+ empty: function(element) {
+ return $(element).innerHTML.blank();
+ },
+
+ descendantOf: function(element, ancestor) {
+ element = $(element), ancestor = $(ancestor);
+ while (element = element.parentNode)
+ if (element == ancestor) return true;
+ return false;
+ },
+
+ scrollTo: function(element) {
+ element = $(element);
+ var pos = Position.cumulativeOffset(element);
+ window.scrollTo(pos[0], pos[1]);
+ return element;
+ },
+
+ getStyle: function(element, style) {
+ element = $(element);
+ style = style == 'float' ? 'cssFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css[style] : null;
+ }
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+ return value == 'auto' ? null : value;
+ },
+
+ getOpacity: function(element) {
+ return $(element).getStyle('opacity');
+ },
+
+ setStyle: function(element, styles, camelized) {
+ element = $(element);
+ var elementStyle = element.style;
+
+ for (var property in styles)
+ if (property == 'opacity') element.setOpacity(styles[property])
+ else
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
+ (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
+ (camelized ? property : property.camelize())] = styles[property];
+
+ return element;
+ },
+
+ setOpacity: function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
+ return element;
+ },
+
+ getDimensions: function(element) {
+ element = $(element);
+ var display = $(element).getStyle('display');
+ if (display != 'none' && display != null) // Safari bug
+ 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;
+ var originalDisplay = els.display;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = 'block';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = originalDisplay;
+ 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;
+ }
+ }
+ return element;
+ },
+
+ 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 = '';
+ }
+ return element;
+ },
+
+ makeClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return element;
+ element._overflow = element.style.overflow || 'auto';
+ if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+ element.style.overflow = 'hidden';
+ return element;
+ },
+
+ undoClipping: function(element) {
+ element = $(element);
+ if (!element._overflow) return element;
+ element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+ element._overflow = null;
+ return element;
+ }
+};
+
+Object.extend(Element.Methods, {
+ childOf: Element.Methods.descendantOf,
+ childElements: Element.Methods.immediateDescendants
+});
+
+if (Prototype.Browser.Opera) {
+ Element.Methods._getStyle = Element.Methods.getStyle;
+ Element.Methods.getStyle = function(element, style) {
+ switch(style) {
+ case 'left':
+ case 'top':
+ case 'right':
+ case 'bottom':
+ if (Element._getStyle(element, 'position') == 'static') return null;
+ default: return Element._getStyle(element, style);
+ }
+ };
+}
+else if (Prototype.Browser.IE) {
+ Element.Methods.getStyle = function(element, style) {
+ element = $(element);
+ style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value && element.currentStyle) value = element.currentStyle[style];
+
+ if (style == 'opacity') {
+ if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if (value[1]) return parseFloat(value[1]) / 100;
+ return 1.0;
+ }
+
+ if (value == 'auto') {
+ if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+ return element['offset'+style.capitalize()] + 'px';
+ return null;
+ }
+ return value;
+ };
+
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ var filter = element.getStyle('filter'), style = element.style;
+ if (value == 1 || value === '') {
+ style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
+ return element;
+ } else if (value < 0.00001) value = 0;
+ style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
+ 'alpha(opacity=' + (value * 100) + ')';
+ return element;
+ };
+
+ // IE is missing .innerHTML support for TABLE-related elements
+ Element.Methods.update = function(element, html) {
+ element = $(element);
+ html = typeof html == 'undefined' ? '' : html.toString();
+ var tagName = element.tagName.toUpperCase();
+ if (['THEAD','TBODY','TR','TD'].include(tagName)) {
+ var div = document.createElement('div');
+ switch (tagName) {
+ case 'THEAD':
+ case 'TBODY':
+ div.innerHTML = '<table><tbody>' + html.stripScripts() + '</tbody></table>';
+ depth = 2;
+ break;
+ case 'TR':
+ div.innerHTML = '<table><tbody><tr>' + html.stripScripts() + '</tr></tbody></table>';
+ depth = 3;
+ break;
+ case 'TD':
+ div.innerHTML = '<table><tbody><tr><td>' + html.stripScripts() + '</td></tr></tbody></table>';
+ depth = 4;
+ }
+ $A(element.childNodes).each(function(node) { element.removeChild(node) });
+ depth.times(function() { div = div.firstChild });
+ $A(div.childNodes).each(function(node) { element.appendChild(node) });
+ } else {
+ element.innerHTML = html.stripScripts();
+ }
+ setTimeout(function() { html.evalScripts() }, 10);
+ return element;
+ }
+}
+else if (Prototype.Browser.Gecko) {
+ Element.Methods.setOpacity = function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1) ? 0.999999 :
+ (value === '') ? '' : (value < 0.00001) ? 0 : value;
+ return element;
+ };
+}
+
+Element._attributeTranslations = {
+ names: {
+ colspan: "colSpan",
+ rowspan: "rowSpan",
+ valign: "vAlign",
+ datetime: "dateTime",
+ accesskey: "accessKey",
+ tabindex: "tabIndex",
+ enctype: "encType",
+ maxlength: "maxLength",
+ readonly: "readOnly",
+ longdesc: "longDesc"
+ },
+ values: {
+ _getAttr: function(element, attribute) {
+ return element.getAttribute(attribute, 2);
+ },
+ _flag: function(element, attribute) {
+ return $(element).hasAttribute(attribute) ? attribute : null;
+ },
+ style: function(element) {
+ return element.style.cssText.toLowerCase();
+ },
+ title: function(element) {
+ var node = element.getAttributeNode('title');
+ return node.specified ? node.nodeValue : null;
+ }
+ }
+};
+
+(function() {
+ Object.extend(this, {
+ href: this._getAttr,
+ src: this._getAttr,
+ disabled: this._flag,
+ checked: this._flag,
+ readonly: this._flag,
+ multiple: this._flag
+ });
+}).call(Element._attributeTranslations.values);
+
+Element.Methods.Simulated = {
+ hasAttribute: function(element, attribute) {
+ var t = Element._attributeTranslations, node;
+ attribute = t.names[attribute] || attribute;
+ node = $(element).getAttributeNode(attribute);
+ return node && node.specified;
+ }
+};
+
+Element.Methods.ByTag = {};
+
+Object.extend(Element, Element.Methods);
+
+if (!Prototype.BrowserFeatures.ElementExtensions &&
+ document.createElement('div').__proto__) {
+ window.HTMLElement = {};
+ window.HTMLElement.prototype = document.createElement('div').__proto__;
+ Prototype.BrowserFeatures.ElementExtensions = true;
+}
+
+Element.hasAttribute = function(element, attribute) {
+ if (element.hasAttribute) return element.hasAttribute(attribute);
+ return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods) {
+ var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+ if (arguments.length == 2) {
+ var tagName = methods;
+ methods = arguments[1];
+ }
+
+ if (!tagName) Object.extend(Element.Methods, methods || {});
+ else {
+ if (tagName.constructor == Array) tagName.each(extend);
+ else extend(tagName);
+ }
+
+ function extend(tagName) {
+ tagName = tagName.toUpperCase();
+ if (!Element.Methods.ByTag[tagName])
+ Element.Methods.ByTag[tagName] = {};
+ Object.extend(Element.Methods.ByTag[tagName], methods);
+ }
+
+ function copy(methods, destination, onlyIfAbsent) {
+ onlyIfAbsent = onlyIfAbsent || false;
+ var cache = Element.extend.cache;
+ for (var property in methods) {
+ var value = methods[property];
+ if (!onlyIfAbsent || !(property in destination))
+ destination[property] = cache.findOrStore(value);
+ }
+ }
+
+ function findDOMClass(tagName) {
+ var klass;
+ var trans = {
+ "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
+ "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
+ "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
+ "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
+ "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
+ "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
+ "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
+ "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
+ "FrameSet", "IFRAME": "IFrame"
+ };
+ if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName + 'Element';
+ if (window[klass]) return window[klass];
+ klass = 'HTML' + tagName.capitalize() + 'Element';
+ if (window[klass]) return window[klass];
+
+ window[klass] = {};
+ window[klass].prototype = document.createElement(tagName).__proto__;
+ return window[klass];
+ }
+
+ if (F.ElementExtensions) {
+ copy(Element.Methods, HTMLElement.prototype);
+ copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+ }
+
+ if (F.SpecificElementExtensions) {
+ for (var tag in Element.Methods.ByTag) {
+ var klass = findDOMClass(tag);
+ if (typeof klass == "undefined") continue;
+ copy(T[tag], klass.prototype);
+ }
+ }
+
+ Object.extend(Element, Element.Methods);
+ delete Element.ByTag;
+};
+
+var 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) {
+ var tagName = this.element.tagName.toUpperCase();
+ if (['TBODY', 'TR'].include(tagName)) {
+ 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($A(this).concat(classNameToAdd).join(' '));
+ },
+
+ remove: function(classNameToRemove) {
+ if (!this.include(classNameToRemove)) return;
+ this.set($A(this).without(classNameToRemove).join(' '));
+ },
+
+ toString: function() {
+ return $A(this).join(' ');
+ }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
+ * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
+ * license. Please see http://www.yui-ext.com/ for more information. */
+
+var Selector = Class.create();
+
+Selector.prototype = {
+ initialize: function(expression) {
+ this.expression = expression.strip();
+ this.compileMatcher();
+ },
+
+ compileMatcher: function() {
+ // Selectors with namespaced attributes can't use the XPath version
+ if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
+ return this.compileXPathMatcher();
+
+ var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
+ c = Selector.criteria, le, p, m;
+
+ if (Selector._cache[e]) {
+ this.matcher = Selector._cache[e]; return;
+ }
+ this.matcher = ["this.matcher = function(root) {",
+ "var r = root, h = Selector.handlers, c = false, n;"];
+
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ p = ps[i];
+ if (m = e.match(p)) {
+ this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
+ new Template(c[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.matcher.push("return h.unique(n);\n}");
+ eval(this.matcher.join('\n'));
+ Selector._cache[this.expression] = this.matcher;
+ },
+
+ compileXPathMatcher: function() {
+ var e = this.expression, ps = Selector.patterns,
+ x = Selector.xpath, le, m;
+
+ if (Selector._cache[e]) {
+ this.xpath = Selector._cache[e]; return;
+ }
+
+ this.matcher = ['.//*'];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in ps) {
+ if (m = e.match(ps[i])) {
+ this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
+ new Template(x[i]).evaluate(m));
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+
+ this.xpath = this.matcher.join('');
+ Selector._cache[this.expression] = this.xpath;
+ },
+
+ findElements: function(root) {
+ root = root || document;
+ if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+ return this.matcher(root);
+ },
+
+ match: function(element) {
+ return this.findElements(document).include(element);
+ },
+
+ toString: function() {
+ return this.expression;
+ },
+
+ inspect: function() {
+ return "#<Selector:" + this.expression.inspect() + ">";
+ }
+};
+
+Object.extend(Selector, {
+ _cache: {},
+
+ xpath: {
+ descendant: "//*",
+ child: "/*",
+ adjacent: "/following-sibling::*[1]",
+ laterSibling: '/following-sibling::*',
+ tagName: function(m) {
+ if (m[1] == '*') return '';
+ return "[local-name()='" + m[1].toLowerCase() +
+ "' or local-name()='" + m[1].toUpperCase() + "']";
+ },
+ className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+ id: "[@id='#{1}']",
+ attrPresence: "[@#{1}]",
+ attr: function(m) {
+ m[3] = m[5] || m[6];
+ return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+ },
+ pseudo: function(m) {
+ var h = Selector.xpath.pseudos[m[1]];
+ if (!h) return '';
+ if (typeof h === 'function') return h(m);
+ return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+ },
+ operators: {
+ '=': "[@#{1}='#{3}']",
+ '!=': "[@#{1}!='#{3}']",
+ '^=': "[starts-with(@#{1}, '#{3}')]",
+ '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
+ '*=': "[contains(@#{1}, '#{3}')]",
+ '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
+ '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
+ },
+ pseudos: {
+ 'first-child': '[not(preceding-sibling::*)]',
+ 'last-child': '[not(following-sibling::*)]',
+ 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
+ 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
+ 'checked': "[@checked]",
+ 'disabled': "[@disabled]",
+ 'enabled': "[not(@disabled)]",
+ 'not': function(m) {
+ var e = m[6], p = Selector.patterns,
+ x = Selector.xpath, le, m, v;
+
+ var exclusion = [];
+ while (e && le != e && (/\S/).test(e)) {
+ le = e;
+ for (var i in p) {
+ if (m = e.match(p[i])) {
+ v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
+ exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+ e = e.replace(m[0], '');
+ break;
+ }
+ }
+ }
+ return "[not(" + exclusion.join(" and ") + ")]";
+ },
+ 'nth-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+ },
+ 'nth-last-child': function(m) {
+ return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+ },
+ 'nth-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("position() ", m);
+ },
+ 'nth-last-of-type': function(m) {
+ return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+ },
+ 'first-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+ },
+ 'last-of-type': function(m) {
+ m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+ },
+ 'only-of-type': function(m) {
+ var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+ },
+ nth: function(fragment, m) {
+ var mm, formula = m[6], predicate;
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ if (mm = formula.match(/^(\d+)$/)) // digit only
+ return '[' + fragment + "= " + mm[1] + ']';
+ if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (mm[1] == "-") mm[1] = -1;
+ var a = mm[1] ? Number(mm[1]) : 1;
+ var b = mm[2] ? Number(mm[2]) : 0;
+ predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+ "((#{fragment} - #{b}) div #{a} >= 0)]";
+ return new Template(predicate).evaluate({
+ fragment: fragment, a: a, b: b });
+ }
+ }
+ }
+ },
+
+ criteria: {
+ tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
+ className: 'n = h.className(n, r, "#{1}", c); c = false;',
+ id: 'n = h.id(n, r, "#{1}", c); c = false;',
+ attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
+ attr: function(m) {
+ m[3] = (m[5] || m[6]);
+ return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
+ },
+ pseudo: function(m) {
+ if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+ return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+ },
+ descendant: 'c = "descendant";',
+ child: 'c = "child";',
+ adjacent: 'c = "adjacent";',
+ laterSibling: 'c = "laterSibling";'
+ },
+
+ patterns: {
+ // combinators must be listed first
+ // (and descendant needs to be last combinator)
+ laterSibling: /^\s*~\s*/,
+ child: /^\s*>\s*/,
+ adjacent: /^\s*\+\s*/,
+ descendant: /^\s/,
+
+ // selectors follow
+ tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
+ id: /^#([\w\-\*]+)(\b|$)/,
+ className: /^\.([\w\-\*]+)(\b|$)/,
+ pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s)/,
+ attrPresence: /^\[([\w]+)\]/,
+ attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
+ },
+
+ handlers: {
+ // UTILITY FUNCTIONS
+ // joins two collections
+ concat: function(a, b) {
+ for (var i = 0, node; node = b[i]; i++)
+ a.push(node);
+ return a;
+ },
+
+ // marks an array of nodes for counting
+ mark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._counted = true;
+ return nodes;
+ },
+
+ unmark: function(nodes) {
+ for (var i = 0, node; node = nodes[i]; i++)
+ node._counted = undefined;
+ return nodes;
+ },
+
+ // mark each child node with its position (for nth calls)
+ // "ofType" flag indicates whether we're indexing for nth-of-type
+ // rather than nth-child
+ index: function(parentNode, reverse, ofType) {
+ parentNode._counted = true;
+ if (reverse) {
+ for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+ node = nodes[i];
+ if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+ }
+ } else {
+ for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+ if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
+ }
+ },
+
+ // filters out duplicates and extends all nodes
+ unique: function(nodes) {
+ if (nodes.length == 0) return nodes;
+ var results = [], n;
+ for (var i = 0, l = nodes.length; i < l; i++)
+ if (!(n = nodes[i])._counted) {
+ n._counted = true;
+ results.push(Element.extend(n));
+ }
+ return Selector.handlers.unmark(results);
+ },
+
+ // COMBINATOR FUNCTIONS
+ descendant: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName('*'));
+ return results;
+ },
+
+ child: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
+ if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+ }
+ return results;
+ },
+
+ adjacent: function(nodes) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ var next = this.nextElementSibling(node);
+ if (next) results.push(next);
+ }
+ return results;
+ },
+
+ laterSibling: function(nodes) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ h.concat(results, Element.nextSiblings(node));
+ return results;
+ },
+
+ nextElementSibling: function(node) {
+ while (node = node.nextSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ previousElementSibling: function(node) {
+ while (node = node.previousSibling)
+ if (node.nodeType == 1) return node;
+ return null;
+ },
+
+ // TOKEN FUNCTIONS
+ tagName: function(nodes, root, tagName, combinator) {
+ tagName = tagName.toUpperCase();
+ var results = [], h = Selector.handlers;
+ if (nodes) {
+ if (combinator) {
+ // fastlane for ordinary descendant combinators
+ if (combinator == "descendant") {
+ for (var i = 0, node; node = nodes[i]; i++)
+ h.concat(results, node.getElementsByTagName(tagName));
+ return results;
+ } else nodes = this[combinator](nodes);
+ if (tagName == "*") return nodes;
+ }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.tagName.toUpperCase() == tagName) results.push(node);
+ return results;
+ } else return root.getElementsByTagName(tagName);
+ },
+
+ id: function(nodes, root, id, combinator) {
+ var targetNode = $(id), h = Selector.handlers;
+ if (!nodes && root == document) return targetNode ? [targetNode] : [];
+ if (nodes) {
+ if (combinator) {
+ if (combinator == 'child') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (targetNode.parentNode == node) return [targetNode];
+ } else if (combinator == 'descendant') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.descendantOf(targetNode, node)) return [targetNode];
+ } else if (combinator == 'adjacent') {
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Selector.handlers.previousElementSibling(targetNode) == node)
+ return [targetNode];
+ } else nodes = h[combinator](nodes);
+ }
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node == targetNode) return [targetNode];
+ return [];
+ }
+ return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+ },
+
+ className: function(nodes, root, className, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ return Selector.handlers.byClassName(nodes, root, className);
+ },
+
+ byClassName: function(nodes, root, className) {
+ if (!nodes) nodes = Selector.handlers.descendant([root]);
+ var needle = ' ' + className + ' ';
+ for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+ nodeClassName = node.className;
+ if (nodeClassName.length == 0) continue;
+ if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+ results.push(node);
+ }
+ return results;
+ },
+
+ attrPresence: function(nodes, root, attr) {
+ var results = [];
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (Element.hasAttribute(node, attr)) results.push(node);
+ return results;
+ },
+
+ attr: function(nodes, root, attr, value, operator) {
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ var handler = Selector.operators[operator], results = [];
+ for (var i = 0, node; node = nodes[i]; i++) {
+ var nodeValue = Element.readAttribute(node, attr);
+ if (nodeValue === null) continue;
+ if (handler(nodeValue, value)) results.push(node);
+ }
+ return results;
+ },
+
+ pseudo: function(nodes, name, value, root, combinator) {
+ if (nodes && combinator) nodes = this[combinator](nodes);
+ if (!nodes) nodes = root.getElementsByTagName("*");
+ return Selector.pseudos[name](nodes, value, root);
+ }
+ },
+
+ pseudos: {
+ 'first-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.previousElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'last-child': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ if (Selector.handlers.nextElementSibling(node)) continue;
+ results.push(node);
+ }
+ return results;
+ },
+ 'only-child': function(nodes, value, root) {
+ var h = Selector.handlers;
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+ results.push(node);
+ return results;
+ },
+ 'nth-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root);
+ },
+ 'nth-last-child': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true);
+ },
+ 'nth-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, false, true);
+ },
+ 'nth-last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, formula, root, true, true);
+ },
+ 'first-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, false, true);
+ },
+ 'last-of-type': function(nodes, formula, root) {
+ return Selector.pseudos.nth(nodes, "1", root, true, true);
+ },
+ 'only-of-type': function(nodes, formula, root) {
+ var p = Selector.pseudos;
+ return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
+ },
+
+ // handles the an+b logic
+ getIndices: function(a, b, total) {
+ if (a == 0) return b > 0 ? [b] : [];
+ return $R(1, total).inject([], function(memo, i) {
+ if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+ return memo;
+ });
+ },
+
+ // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
+ nth: function(nodes, formula, root, reverse, ofType) {
+ if (nodes.length == 0) return [];
+ if (formula == 'even') formula = '2n+0';
+ if (formula == 'odd') formula = '2n+1';
+ var h = Selector.handlers, results = [], indexed = [], m;
+ h.mark(nodes);
+ for (var i = 0, node; node = nodes[i]; i++) {
+ if (!node.parentNode._counted) {
+ h.index(node.parentNode, reverse, ofType);
+ indexed.push(node.parentNode);
+ }
+ }
+ if (formula.match(/^\d+$/)) { // just a number
+ formula = Number(formula);
+ for (var i = 0, node; node = nodes[i]; i++)
+ if (node.nodeIndex == formula) results.push(node);
+ } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+ if (m[1] == "-") m[1] = -1;
+ var a = m[1] ? Number(m[1]) : 1;
+ var b = m[2] ? Number(m[2]) : 0;
+ var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+ for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+ for (var j = 0; j < l; j++)
+ if (node.nodeIndex == indices[j]) results.push(node);
+ }
+ }
+ h.unmark(nodes);
+ h.unmark(indexed);
+ return results;
+ },
+
+ 'empty': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++) {
+ // IE treats comments as element nodes
+ if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
+ results.push(node);
+ }
+ return results;
+ },
+
+ 'not': function(nodes, selector, root) {
+ var h = Selector.handlers, selectorType, m;
+ var exclusions = new Selector(selector).findElements(root);
+ h.mark(exclusions);
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node._counted) results.push(node);
+ h.unmark(exclusions);
+ return results;
+ },
+
+ 'enabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (!node.disabled) results.push(node);
+ return results;
+ },
+
+ 'disabled': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.disabled) results.push(node);
+ return results;
+ },
+
+ 'checked': function(nodes, value, root) {
+ for (var i = 0, results = [], node; node = nodes[i]; i++)
+ if (node.checked) results.push(node);
+ return results;
+ }
+ },
+
+ operators: {
+ '=': function(nv, v) { return nv == v; },
+ '!=': function(nv, v) { return nv != v; },
+ '^=': function(nv, v) { return nv.startsWith(v); },
+ '$=': function(nv, v) { return nv.endsWith(v); },
+ '*=': function(nv, v) { return nv.include(v); },
+ '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
+ '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
+ },
+
+ matchElements: function(elements, expression) {
+ var matches = new Selector(expression).findElements(), h = Selector.handlers;
+ h.mark(matches);
+ for (var i = 0, results = [], element; element = elements[i]; i++)
+ if (element._counted) results.push(element);
+ h.unmark(matches);
+ return results;
+ },
+
+ findElement: function(elements, expression, index) {
+ if (typeof expression == 'number') {
+ index = expression; expression = false;
+ }
+ return Selector.matchElements(elements, expression || '*')[index || 0];
+ },
+
+ findChildElements: function(element, expressions) {
+ var exprs = expressions.join(','), expressions = [];
+ exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+ expressions.push(m[1].strip());
+ });
+ var results = [], h = Selector.handlers;
+ for (var i = 0, l = expressions.length, selector; i < l; i++) {
+ selector = new Selector(expressions[i].strip());
+ h.concat(results, selector.findElements(element));
+ }
+ return (l > 1) ? h.unique(results) : results;
+ }
+});
+
+function $$() {
+ return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+ reset: function(form) {
+ $(form).reset();
+ return form;
+ },
+
+ serializeElements: function(elements, getHash) {
+ var data = elements.inject({}, function(result, element) {
+ if (!element.disabled && element.name) {
+ var key = element.name, value = $(element).getValue();
+ if (value != null) {
+ if (key in result) {
+ if (result[key].constructor != Array) result[key] = [result[key]];
+ result[key].push(value);
+ }
+ else result[key] = value;
+ }
+ }
+ return result;
+ });
+
+ return getHash ? data : Hash.toQueryString(data);
+ }
+};
+
+Form.Methods = {
+ serialize: function(form, getHash) {
+ return Form.serializeElements(Form.getElements(form), getHash);
+ },
+
+ getElements: function(form) {
+ return $A($(form).getElementsByTagName('*')).inject([],
+ function(elements, child) {
+ if (Form.Element.Serializers[child.tagName.toLowerCase()])
+ elements.push(Element.extend(child));
+ return elements;
+ }
+ );
+ },
+
+ getInputs: function(form, typeName, name) {
+ form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+ for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+ var input = inputs[i];
+ if ((typeName && input.type != typeName) || (name && input.name != name))
+ continue;
+ matchingInputs.push(Element.extend(input));
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function(form) {
+ form = $(form);
+ Form.getElements(form).invoke('disable');
+ return form;
+ },
+
+ enable: function(form) {
+ form = $(form);
+ Form.getElements(form).invoke('enable');
+ return form;
+ },
+
+ findFirstElement: function(form) {
+ return $(form).getElements().find(function(element) {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
+ focusFirstElement: function(form) {
+ form = $(form);
+ form.findFirstElement().activate();
+ return form;
+ },
+
+ request: function(form, options) {
+ form = $(form), options = Object.clone(options || {});
+
+ var params = options.parameters;
+ options.parameters = form.serialize(true);
+
+ if (params) {
+ if (typeof params == 'string') params = params.toQueryParams();
+ Object.extend(options.parameters, params);
+ }
+
+ if (form.hasAttribute('method') && !options.method)
+ options.method = form.method;
+
+ return new Ajax.Request(form.readAttribute('action'), options);
+ }
+}
+
+Object.extend(Form, Form.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+ focus: function(element) {
+ $(element).focus();
+ return element;
+ },
+
+ select: function(element) {
+ $(element).select();
+ return element;
+ }
+}
+
+Form.Element.Methods = {
+ serialize: function(element) {
+ element = $(element);
+ if (!element.disabled && element.name) {
+ var value = element.getValue();
+ if (value != undefined) {
+ var pair = {};
+ pair[element.name] = value;
+ return Hash.toQueryString(pair);
+ }
+ }
+ return '';
+ },
+
+ getValue: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ return Form.Element.Serializers[method](element);
+ },
+
+ clear: function(element) {
+ $(element).value = '';
+ return element;
+ },
+
+ present: function(element) {
+ return $(element).value != '';
+ },
+
+ activate: function(element) {
+ element = $(element);
+ try {
+ element.focus();
+ if (element.select && (element.tagName.toLowerCase() != 'input' ||
+ !['button', 'reset', 'submit'].include(element.type)))
+ element.select();
+ } catch (e) {}
+ return element;
+ },
+
+ disable: function(element) {
+ element = $(element);
+ element.blur();
+ element.disabled = true;
+ return element;
+ },
+
+ enable: function(element) {
+ element = $(element);
+ element.disabled = false;
+ return element;
+ }
+}
+
+Object.extend(Form.Element, Form.Element.Methods);
+Object.extend(Element.Methods.ByTag, {
+ "FORM": Object.clone(Form.Methods),
+ "INPUT": Object.clone(Form.Element.Methods),
+ "SELECT": Object.clone(Form.Element.Methods),
+ "TEXTAREA": Object.clone(Form.Element.Methods)
+});
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+ input: function(element) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element);
+ default:
+ return Form.Element.Serializers.textarea(element);
+ }
+ },
+
+ inputSelector: function(element) {
+ return element.checked ? element.value : null;
+ },
+
+ textarea: function(element) {
+ return element.value;
+ },
+
+ select: function(element) {
+ return this[element.type == 'select-one' ?
+ 'selectOne' : 'selectMany'](element);
+ },
+
+ selectOne: function(element) {
+ var index = element.selectedIndex;
+ return index >= 0 ? this.optionValue(element.options[index]) : null;
+ },
+
+ selectMany: function(element) {
+ var values, length = element.length;
+ if (!length) return null;
+
+ for (var i = 0, values = []; i < length; i++) {
+ var opt = element.options[i];
+ if (opt.selected) values.push(this.optionValue(opt));
+ }
+ return values;
+ },
+
+ optionValue: function(opt) {
+ // extend element because hasAttribute may not be native
+ return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+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();
+ var changed = ('string' == typeof this.lastValue && 'string' == typeof value
+ ? this.lastValue != value : String(this.lastValue) != String(value));
+ if (changed) {
+ 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() {
+ Form.getElements(this.element).each(this.registerCallback.bind(this));
+ },
+
+ registerCallback: function(element) {
+ if (element.type) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
+ break;
+ default:
+ 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,
+ KEY_HOME: 36,
+ KEY_END: 35,
+ KEY_PAGEUP: 33,
+ KEY_PAGEDOWN: 34,
+
+ 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, length = Event.observers.length; i < length; i++) {
+ Event.stopObserving.apply(this, Event.observers[i]);
+ Event.observers[i][0] = null;
+ }
+ Event.observers = false;
+ },
+
+ observe: function(element, name, observer, useCapture) {
+ element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (Prototype.Browser.WebKit || element.attachEvent))
+ name = 'keydown';
+
+ Event._observeAndCache(element, name, observer, useCapture);
+ },
+
+ stopObserving: function(element, name, observer, useCapture) {
+ element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (Prototype.Browser.WebKit || element.attachEvent))
+ name = 'keydown';
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, observer, useCapture);
+ } else if (element.detachEvent) {
+ try {
+ element.detachEvent('on' + name, observer);
+ } catch (e) {}
+ }
+ }
+});
+
+/* prevent memory leaks in IE */
+if (Prototype.Browser.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) {
+ if(element.tagName=='BODY') break;
+ var 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;
+ },
+
+ 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 {
+ if (!window.opera || element.tagName=='BODY') {
+ 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 (Prototype.Browser.WebKit) {
+ 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];
+ }
+}
+
+Element.addMethods();
\ 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.
+ **/
+
+
+// This module does NOT depend on prototype.js
+
+var Rico = {
+ Version: '2.0 beta2',
+ loadRequested: 1,
+ loadComplete: 2,
+ init : function() {
+ try { // fix IE background image flicker (credit: www.mister-pixel.com)
+ document.execCommand("BackgroundImageCache", false, true);
+ } catch(err) {}
+ this.preloadMsgs='';
+ var elements = document.getElementsByTagName('script');
+ this.baseHref= location.protocol + "//" + location.host;
+ this.loadedFiles={};
+ this.loadQueue=[];
+ this.windowIsLoaded=false;
+ this.onLoadCallbacks=[];
+ for (var i=0; i<elements.length; i++) {
+ if (!elements[i].src) continue;
+ var src = elements[i].src;
+ var slashIdx = src.lastIndexOf('/');
+ var path = src.substring(0, slashIdx+1);
+ var filename = src.substring(slashIdx+1);
+ this.loadedFiles[filename]=this.loadComplete;
+ if (filename == 'rico.js') {
+ this.jsDir = path;
+ this.cssDir= path+'css/';
+ this.imgDir= path+'images/';
+ this.htmDir= path;
+ this.xslDir= path;
+ }
+ }
+ if (typeof Prototype=='undefined')
+ this.include('prototype.js');
+ this.include('ricoCommon.js');
+ var func=function() { Rico.windowLoaded(); };
+ if (window.addEventListener)
+ window.addEventListener('load', func, false);
+ else if (window.attachEvent)
+ window.attachEvent('onload', func);
+ this.onLoad(function() { Rico.writeDebugMsg('Pre-load messages:\n'+Rico.preloadMsgs); });
+ },
+
+ // Array entries can reference a javascript file or css stylesheet
+ // A dependency on another module can be indicated with a plus-sign prefix: '+DependsOnModule'
+ moduleDependencies : {
+ Accordion : ['ricoBehaviors.js','ricoEffects.js','ricoComponents.js'],
+ Color : ['ricoColor.js'],
+ Corner : ['ricoStyles.js'],
+ DragAndDrop: ['ricoDragDrop.js'],
+ Effect : ['ricoEffects.js'],
+ Calendar : ['ricoCalendar.js', 'ricoCalendar.css'],
+ Tree : ['ricoTree.js', 'ricoTree.css'],
+ ColorPicker: ['ricoColorPicker.js', 'ricoStyles.js'],
+ SimpleGrid : ['ricoCommon.js', 'ricoGridCommon.js', 'ricoGrid.css', 'ricoSimpleGrid.js'],
+ LiveGrid : ['ricoCommon.js', 'ricoGridCommon.js', 'ricoGrid.css', 'ricoBehaviors.js', 'ricoLiveGrid.js'],
+ CustomMenu : ['ricoMenu.js', 'ricoMenu.css'],
+ LiveGridMenu : ['+CustomMenu', 'ricoLiveGridMenu.js'],
+ LiveGridAjax : ['+LiveGrid', 'ricoLiveGridAjax.js'],
+ LiveGridForms: ['+LiveGridAjax', '+LiveGridMenu', '+Accordion', '+Corner', 'ricoLiveGridForms.js', 'ricoLiveGridForms.css'],
+ SpreadSheet : ['+SimpleGrid', 'ricoSheet.js']
+ },
+
+ // not reliable when used with XSLT
+ loadModule : function(name) {
+ var dep=this.moduleDependencies[name];
+ if (!dep) return;
+ for (var i=0; i<dep.length; i++)
+ if (dep[i].substring(0,1)=='+')
+ this.loadModule(dep[i].slice(1));
+ else
+ this.include(dep[i]);
+ },
+
+ // not reliable when used with XSLT
+ include : function(filename) {
+ if (this.loadedFiles[filename]) return;
+ this.addPreloadMsg('include: '+filename);
+ var ext = filename.substr(filename.lastIndexOf('.')+1);
+ switch (ext.toLowerCase()) {
+ case 'js':
+ this.loadQueue.push(filename);
+ this.loadedFiles[filename]=this.loadRequested;
+ this.checkLoadQueue();
+ return;
+ case 'css':
+ var el = document.createElement('link');
+ el.type = 'text/css';
+ el.rel = 'stylesheet'
+ el.href = this.cssDir+filename;
+ this.loadedFiles[filename]=this.loadComplete;
+ document.getElementsByTagName('head')[0].appendChild(el);
+ return;
+ }
+ },
+
+ checkLoadQueue: function() {
+ if (this.loadQueue.length==0) return;
+ if (this.inProcess) return; // seems to only be required by IE, but applied to all browsers just to be safe
+ this.addScriptToDOM(this.loadQueue.shift());
+ },
+
+ addScriptToDOM: function(filename) {
+ this.addPreloadMsg('addScriptToDOM: '+filename);
+ var js = document.createElement('script');
+ js.type = 'text/javascript';
+ js.src = this.jsDir+filename;
+ this.loadedFiles[filename]=this.loadRequested;
+ this.inProcess=filename;
+ var head=document.getElementsByTagName('head')[0];
+ if (filename.substring(0,4)=='rico') {
+ head.appendChild(js);
+ } else if(/WebKit|Khtml/i.test(navigator.userAgent)) {
+ head.appendChild(js);
+ this.includeLoaded(filename);
+ } else {
+ js.onload = js.onreadystatechange = function() {
+ if (js.readyState && js.readyState != 'loaded' && js.readyState != 'complete') return;
+ js.onreadystatechange = js.onload = null;
+ Rico.includeLoaded(filename);
+ };
+ head.appendChild(js);
+ }
+ },
+
+ // called after a script file has finished loading
+ includeLoaded: function(filename) {
+ this.addPreloadMsg('loaded: '+filename);
+ this.loadedFiles[filename]=this.loadComplete;
+ if (filename==this.inProcess) {
+ this.inProcess=null;
+ this.checkLoadQueue();
+ this.checkIfComplete();
+ }
+ },
+
+ // called by the document onload event
+ windowLoaded: function() {
+ this.windowIsLoaded=true;
+ this.checkIfComplete();
+ },
+
+ checkIfComplete: function() {
+ var waitingFor=this.windowIsLoaded ? '' : 'window';
+ for(var filename in this.loadedFiles) {
+ if (this.loadedFiles[filename]==this.loadRequested)
+ waitingFor+=' '+filename;
+ }
+ //window.status='waitingFor: '+waitingFor;
+ this.addPreloadMsg('waitingFor: '+waitingFor);
+ if (waitingFor.length==0) {
+ this.addPreloadMsg('Processing callbacks');
+ while (this.onLoadCallbacks.length > 0) {
+ var callback=this.onLoadCallbacks.pop();
+ if (callback) callback();
+ }
+ }
+ },
+
+ onLoad: function(callback) {
+ this.onLoadCallbacks.push(callback);
+ this.checkIfComplete();
+ },
+
+ isKonqueror : navigator.userAgent.toLowerCase().indexOf("konqueror") >= 0,
+
+ // logging funtions
+
+ startTime : new Date(),
+
+ timeStamp: function() {
+ var stamp = new Date();
+ return (stamp.getTime()-this.startTime.getTime())+": ";
+ },
+
+ setDebugArea: function(id, forceit) {
+ if (!this.debugArea || forceit) {
+ var newarea=document.getElementById(id);
+ if (!newarea) return;
+ this.debugArea=newarea;
+ newarea.value='';
+ }
+ },
+
+ addPreloadMsg: function(msg) {
+ this.preloadMsgs+=Rico.timeStamp()+msg+"\n";
+ },
+
+ writeDebugMsg: function(msg, resetFlag) {
+ if (this.debugArea) {
+ if (resetFlag) this.debugArea.value='';
+ this.debugArea.value+=this.timeStamp()+msg+"\n";
+ }
+ }
+
+}
+
+Rico.init();
--- /dev/null
+//-------------------- 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);
+ }
+
+}
+
+Rico.includeLoaded('ricoAjaxEngine.js');
\ No newline at end of file
--- /dev/null
+/**
+ * (c) 2005-2007 Richard Cowin (http://openrico.org)
+ *
+ * Rico is 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
+ **/
+
+
+Rico.selectionSet = function(set, options){
+ new Rico.SelectionSet(set, options)
+}
+
+Rico.SelectionSet = Class.create();
+Rico.SelectionSet.prototype = {
+ initialize: function(selectionSet, options){
+ this.options = options || {}
+ if (typeof selectionSet == 'string')
+ selectionSet = $$(selectionSet)
+ this.previouslySelected = [];
+ this.selectionSet = selectionSet;
+ this.selectedClassName = this.options.selectedClass || "selected";
+ this.selectNode = this.options.selectNode || function(e){return e};
+ this.onSelect = this.options.onSelect;
+ this.onFirstSelect = this.options.onFirstSelect;
+ this.clickHandler = this.click.bind(this);
+ selectionSet.each(function(e) {Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,e).wrapper);}.bind(this))
+ if (!this.options.noDefault)
+ this.selectIndex(this.options.selectedIndex || 0)
+ },
+ reset: function(){
+ this.previouslySelected = [];
+ this.notifySelected(this.selected);
+ },
+ select: function(element){
+ if (this.selected == element)
+ return;
+
+ if (this.selected)
+ new Element.ClassNames(this.selectNode(this.selected)).remove(this.selectedClassName)
+
+ this.notifySelected(element)
+
+ this.selected = element;
+ new Element.ClassNames(this.selectNode(this.selected)).add(this.selectedClassName)
+ },
+ notifySelected: function(element){
+ var index = this.selectionSet.indexOf(element)
+ if (this.onFirstSelect && !this.previouslySelected[index]){
+ this.onFirstSelect(element, index)
+ this.previouslySelected[index] = true;
+ }
+ if (this.onSelect)
+ try{
+ this.onSelect(element, index)
+ } catch (e) {}
+ },
+ selectIndex: function(index){
+ this.select(this.selectionSet[index])
+ },
+ nextSelectItem: function(index){
+ var index = this.selectionSet.indexOf(this.selected)
+ if (index + 1 >= this.selectionSet.length)
+ return this.selectionSet[index - 1];
+ else
+ return this.selectionSet[index + 1];
+ },
+ selectNext: function(){
+ var index = this.selectionSet.indexOf(this.selected)
+ if (index >= this.selectionSet.length)
+ this.selectIndex(index - 1)
+ else
+ this.selectIndex(index + 1)
+ },
+ click: function(event,target) {
+ this.select(target);
+ },
+ add: function(item){
+ // this.selectionSet.push(item)
+ if (item.constructur == Array)
+ item.each(function(e){
+ Event.observe(e, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper);
+ }.bind(this))
+ else
+ Event.observe(item, "click", new Rico.EventWrapper(this.clickHandler,item).wrapper);
+ },
+ remove: function(item){
+ this.selectionSet = this.selectionSet.without(item)
+ //Todo: need to cleanup all events on item - need to keep track of eventwrappers
+ },
+ removeAll: function(){
+
+ }
+ }
+
+Rico.HoverSet = Class.create();
+Rico.HoverSet.prototype = {
+ initialize: function(hoverSet, options){
+ options = options || [];
+ this.hoverSet = hoverSet;
+ this.hoverClassName = options.hoverClass || "hover";
+ this.hoverNodes = options.hoverNodes || function(e){return [e]};
+ this.listenerHover = this._onHover.bind(this)
+ this.listenerEndHover = this._onUnHover.bind(this)
+
+ this.hoverSet.each((function(e) {Event.observe(e, "mousemove", new Rico.EventWrapper(this.listenerHover,e).wrapper);}).bind(this))
+ this.hoverSet.each((function(e) {Event.observe(e, "mouseout", new Rico.EventWrapper(this.listenerEndHover,e).wrapper);}).bind(this))
+ },
+ _onHover: function(event,target) {
+ this.hover(target);
+ },
+ _onUnHover: function(event,target) {
+ this.unHover(target);
+ },
+ hover: function(target) {
+ this.hoverNodes(target).each((function(t){Element.classNames(t).add(this.hoverClassName)}).bind(this));
+ },
+ unHover: function(target) {
+ this.hoverNodes(target).each((function(t){Element.classNames(t).remove(this.hoverClassName)}).bind(this));
+ },
+ add: function(item){
+ Event.observe(item, "mousemove", new Rico.EventWrapper(this.listenerHover,item).wrapper);
+ Event.observe(item, "mouseout", new Rico.EventWrapper(this.listenerEndHover,item).wrapper);
+ },
+ remove: function(item){
+ //Todo: need to cleanup all events on item - need to keep terack of eventwrappers
+ //stopObserving
+ //Event.stopObserving(e, "mousemove", new Rico.EventWrapper(this.listenerHover,e).wrapper);}).bind(this))
+ //this.hoverSet.each((function(e) {Event.observe(e, "mouseout", new Rico.EventWrapper(this.listenerEndHover,e).wrapper);}).bind(this))
+ //hoverSet
+ },
+ removeAll: function(item){
+ }
+}
+
+
+Rico.Hover = {
+ groups: {},
+ clearCurrent: function(group) {
+ var last_hover = Rico.Hover.groups[group];
+ if(!last_hover) return
+ clearTimeout(last_hover[0])
+ last_hover[1].end()
+ Rico.Hover.groups[group] = null;
+ },
+ end: function(group) {
+ Rico.Hover.groups[group][1].end();
+ },
+ endWith: function(hover, group) {
+ var timer = setTimeout('Rico.Hover.end("'+ group + '")', hover.exitDelay)
+ Rico.Hover.groups[group] = [timer, hover]
+ }
+}
+
+Rico.HoverDisplay = Class.create();
+Rico.HoverDisplay.prototype = {
+ initialize: function(element, options) {
+ this.element = element;
+ this.options = options || {};
+ this.group = this.options.group;
+ this.exitDelay = this.options.delay || 1000;
+ },
+ begin: function() {
+ Rico.Hover.clearCurrent(this.group)
+ Element.show(this.element)
+ },
+ end: function(delay) {
+ if(delay)
+ Rico.Hover.endWith(this, this.group);
+ else
+ Element.hide(this.element)
+ }
+}
+
+
+Rico.EventWrapper = Class.create();
+Rico.EventWrapper.prototype = {
+ initialize: function(handler, target){
+ this.handler = handler;
+ this.target = target;
+ this.wrapper = this.wrapperCall.bindAsEventListener(this)
+ },
+ wrapperCall: function(event){
+ this.handler(event, this.target)
+ }
+}
+
+Rico.includeLoaded('ricoBehaviors.js');
--- /dev/null
+// By Matt Brown
+// June-October 2006
+// email: dowdybrown@yahoo.com
+// Implements a pop-up Gregorian calendar.
+// Dates of adoption of the Gregorian calendar vary by country - accurate as a US & British calendar from 14 Sept 1752 to present.
+// Mark special dates with calls to addHoliday()
+// Inspired by code originally written by Tan Ling Wee on 2 Dec 2001
+
+// Requires prototype.js and ricoCommon.js
+
+Rico.CalendarControl = Class.create();
+
+Rico.CalendarControl.prototype = {
+
+ initialize: function(id,options) {
+ this.id=id;
+ var today=new Date();
+ Object.extend(this, new Rico.Popup({ignoreClicks:true}));
+ Object.extend(this.options, {
+ startAt : 0, // week starts with 0=sunday, 1=monday
+ showWeekNumber : 0, // show week number in first column?
+ showToday : 1, // show "Today is..." in footer?
+ cursorColor: '#FDD', // color used to highlight dates as the user moves their mouse
+ repeatInterval : 100, // when left/right arrow is pressed, repeat action every x milliseconds
+ dateFmt : 'ISO8601', // default is ISO-8601, 'rico'=use format stored in ricoTranslate object
+ selectedDateBorder : "#666666", // border to indicate currently selected date
+ minDate : new Date(today.getFullYear()-50,0,1), // default to +-50 yrs from current date
+ maxDate : new Date(today.getFullYear()+50,11,31)
+ });
+ Object.extend(this.options, options || {});
+ this.close=this.closePopup;
+ this.bPageLoaded=false;
+ this.img=new Array();
+ this.Holidays={};
+ this.todayString=RicoTranslate.getPhrase("Today is ");
+ this.weekString=RicoTranslate.getPhrase("Wk");
+ if (this.options.dateFmt=='rico') this.options.dateFmt=RicoTranslate.dateFmt;
+ this.dateParts=new Array();
+ this.re=/^\s*(\w+)(\W)(\w+)(\W)(\w+)/i;
+ if (this.re.exec(this.options.dateFmt)) {
+ this.dateParts[RegExp.$1]=0;
+ this.dateParts[RegExp.$3]=1;
+ this.dateParts[RegExp.$5]=2;
+ }
+ },
+
+
+ // y=0 implies a repeating holiday
+ addHoliday : function(d, m, y, desc, bgColor, txtColor) {
+ this.Holidays[this.holidayKey(y,m-1,d)]={desc:desc, txtColor:txtColor, bgColor:bgColor || '#DDF'};
+ },
+
+ holidayKey : function(y,m,d) {
+ return 'h'+y.toPaddedString(4)+m.toPaddedString(2)+d.toPaddedString(2);
+ },
+
+ atLoad : function() {
+ this.container=document.createElement("div");
+ this.container.style.display="none"
+ this.container.id=this.id;
+ this.container.className='ricoCalContainer';
+
+ this.maintab=document.createElement("table");
+ this.maintab.cellSpacing=0;
+ this.maintab.cellPadding=0;
+ this.maintab.border=0;
+ this.maintab.className='ricoCalTab';
+
+ for (var i=0; i<7; i++) {
+ var r=this.maintab.insertRow(-1);
+ r.className='row'+i;
+ for (var c=0; c<8; c++)
+ r.insertCell(-1);
+ }
+ this.tbody=this.maintab.tBodies[0];
+ var r=this.tbody.rows[0];
+ r.className='ricoCalDayNames';
+ if (this.options.showWeekNumber) {
+ r.cells[0].innerHTML=this.weekString;
+ for (var i=0; i<7; i++)
+ this.tbody.rows[i].cells[0].className='ricoCalWeekNum';
+ }
+ this.styles=[];
+ for (var i=0; i<7; i++) {
+ var dow=(i+this.options.startAt) % 7;
+ r.cells[i+1].innerHTML=RicoTranslate.dayNames[dow].substring(0,3);
+ this.styles[i+1]='ricoCal'+dow;
+ }
+
+ // table header (navigation controls)
+ this.thead=this.maintab.createTHead()
+ var r=this.thead.insertRow(-1);
+ var c=r.insertCell(-1);
+ c.colSpan=8;
+ var img=this.createNavArrow('decMonth','left');
+ c.appendChild(document.createElement("a")).appendChild(img);
+ this.titleMonth=document.createElement("a");
+ c.appendChild(this.titleMonth);
+ Event.observe(this.titleMonth,"click", this.popUpMonth.bindAsEventListener(this), false);
+ var img=this.createNavArrow('incMonth','right');
+ c.appendChild(document.createElement("a")).appendChild(img);
+ var s=document.createElement("span");
+ s.innerHTML=' ';
+ s.style.paddingLeft='3em';
+ c.appendChild(s);
+
+ var img=this.createNavArrow('decYear','left');
+ c.appendChild(document.createElement("a")).appendChild(img);
+ this.titleYear=document.createElement("a");
+ Event.observe(this.titleYear,"click", this.popUpYear.bindAsEventListener(this), false);
+ c.appendChild(this.titleYear);
+ var img=this.createNavArrow('incYear','right');
+ c.appendChild(document.createElement("a")).appendChild(img);
+
+ // table footer (today)
+ if (this.options.showToday) {
+ this.tfoot=this.maintab.createTFoot()
+ var r=this.tfoot.insertRow(-1);
+ this.todayCell=r.insertCell(-1);
+ this.todayCell.colSpan=8;
+ Event.observe(this.todayCell,"click", this.selectNow.bindAsEventListener(this), false);
+ }
+
+
+ this.container.appendChild(this.maintab);
+
+ // close icon (upper right)
+ var img=document.createElement("img");
+ img.src=Rico.imgDir+'close.gif';
+ img.onclick=this.close.bind(this);
+ img.style.cursor='pointer';
+ img.style.position='absolute';
+ img.style.top='1px'; /* assumes a 1px border */
+ img.style.right='1px';
+ this.container.appendChild(img);
+
+ // month selector
+ this.monthSelect=document.createElement("table");
+ this.monthSelect.className='ricoCalMenu';
+ this.monthSelect.cellPadding=2;
+ this.monthSelect.cellSpacing=0;
+ this.monthSelect.border=0;
+ for (var i=0; i<4; i++) {
+ var r=this.monthSelect.insertRow(-1);
+ for (var j=0; j<3; j++) {
+ var c=r.insertCell(-1);
+ var a=document.createElement("a");
+ a.innerHTML=RicoTranslate.monthNames[i*3+j].substring(0,3);
+ a.name=i*3+j;
+ c.appendChild(a);
+ Event.observe(a,"click", this.selectMonth.bindAsEventListener(this), false);
+ }
+ }
+ this.monthSelect.style.display='none';
+ this.container.appendChild(this.monthSelect);
+
+ // fix anchors so they work in IE6
+ var a=this.container.getElementsByTagName('a');
+ for (var i=0; i<a.length; i++)
+ a[i].href='#';
+
+ Event.observe(this.tbody,"click", this.saveAndClose.bindAsEventListener(this));
+ Event.observe(this.tbody,"mouseover", this.mouseOver.bindAsEventListener(this));
+ Event.observe(this.tbody,"mouseout", this.mouseOut.bindAsEventListener(this));
+ document.getElementsByTagName("body")[0].appendChild(this.container);
+ this.setDiv(this.container);
+ this.close()
+ this.bPageLoaded=true
+ },
+
+ selectNow : function() {
+ this.monthSelected=this.monthNow;
+ this.yearSelected=this.yearNow;
+ this.constructCalendar();
+ },
+
+ createNavArrow: function(funcname,gifname) {
+ var img=document.createElement("img");
+ img.src=Rico.imgDir+gifname+'.gif';
+ img.name=funcname;
+ Event.observe(img,"click", this[funcname].bindAsEventListener(this), false);
+ Event.observe(img,"mousedown", this.mouseDown.bindAsEventListener(this), false);
+ Event.observe(img,"mouseup", this.mouseUp.bindAsEventListener(this), false);
+ Event.observe(img,"mouseout", this.mouseUp.bindAsEventListener(this), false);
+ return img
+ },
+
+ mouseOver: function(e) {
+ var el=Event.element(e);
+ if (this.lastHighlight==el) return;
+ this.unhighlight();
+ var s=el.innerHTML.replace(/ /g,'');
+ if (s=='' || el.className=='ricoCalWeekNum') return;
+ var day=parseInt(s);
+ if (isNaN(day)) return;
+ this.lastHighlight=el;
+ this.tmpColor=el.style.backgroundColor;
+ el.style.backgroundColor=this.options.cursorColor;
+ },
+
+ unhighlight: function() {
+ if (!this.lastHighlight) return;
+ this.lastHighlight.style.backgroundColor=this.tmpColor;
+ this.lastHighlight=null;
+ },
+
+ mouseOut: function(e) {
+ var el=Event.element(e);
+ if (el==this.lastHighlight) this.unhighlight();
+ },
+
+ mouseDown: function(e) {
+ var el=Event.element(e);
+ this.repeatFunc=this[el.name].bind(this);
+ this.timeoutID=setTimeout(this.repeatStart.bind(this),500);
+ },
+
+ mouseUp: function(e) {
+ clearTimeout(this.timeoutID);
+ clearInterval(this.intervalID)
+ },
+
+ repeatStart : function() {
+ clearInterval(this.intervalID);
+ this.intervalID=setInterval(this.repeatFunc,this.options.repeatInterval);
+ },
+
+ // is yr/mo within minDate/MaxDate?
+ isValidMonth : function(yr,mo) {
+ if (yr < this.options.minDate.getFullYear()) return false;
+ if (yr == this.options.minDate.getFullYear() && mo < this.options.minDate.getMonth()) return false;
+ if (yr > this.options.maxDate.getFullYear()) return false;
+ if (yr == this.options.maxDate.getFullYear() && mo > this.options.maxDate.getMonth()) return false;
+ return true;
+ },
+
+ incMonth : function() {
+ var newMonth=this.monthSelected+1;
+ var newYear=this.yearSelected;
+ if (newMonth>11) {
+ newMonth=0;
+ newYear++;
+ }
+ if (!this.isValidMonth(newYear,newMonth)) return;
+ this.monthSelected=newMonth;
+ this.yearSelected=newYear;
+ this.constructCalendar()
+ },
+
+ decMonth : function() {
+ var newMonth=this.monthSelected-1;
+ var newYear=this.yearSelected;
+ if (newMonth<0) {
+ newMonth=11;
+ newYear--;
+ }
+ if (!this.isValidMonth(newYear,newMonth)) return;
+ this.monthSelected=newMonth;
+ this.yearSelected=newYear;
+ this.constructCalendar()
+ },
+
+ selectMonth : function(e) {
+ var el=Event.element(e);
+ this.monthSelected=parseInt(el.name);
+ this.constructCalendar();
+ Event.stop(e);
+ },
+
+ popUpMonth : function() {
+ this.monthSelect.style.display=this.monthSelect.style.display=='none' ? 'block' : 'none';
+ },
+
+ popDownMonth : function() {
+ this.monthSelect.style.display='none';
+ },
+
+ /*** Year Pulldown ***/
+
+ popUpYear : function() {
+ var newYear=prompt(RicoTranslate.getPhrase("Year ("+this.options.minDate.getFullYear()+"-"+this.options.maxDate.getFullYear()+")"),this.yearSelected);
+ if (newYear==null) return;
+ newYear=parseInt(newYear);
+ if (isNaN(newYear) || newYear<this.options.minDate.getFullYear() || newYear>this.options.maxDate.getFullYear()) {
+ alert(RicoTranslate.getPhrase("Invalid year"));
+ } else {
+ this.yearSelected=newYear;
+ this.constructCalendar();
+ }
+ },
+
+ incYear : function() {
+ if (this.yearSelected>=this.options.maxDate.getFullYear()) return;
+ this.yearSelected++;
+ this.constructCalendar();
+ },
+
+ decYear : function() {
+ if (this.yearSelected<=this.options.minDate.getFullYear()) return;
+ this.yearSelected--;
+ this.constructCalendar();
+ },
+
+ // tried a number of different week number functions posted on the net
+ // this is the only one that produced consistent results when comparing week numbers for December and the following January
+ WeekNbr : function(year,month,day) {
+ var when = new Date(year,month,day);
+ var newYear = new Date(year,0,1);
+ var offset = 7 + 1 - newYear.getDay();
+ if (offset == 8) offset = 1;
+ var daynum = ((Date.UTC(year,when.getMonth(),when.getDate(),0,0,0) - Date.UTC(year,0,1,0,0,0)) /1000/60/60/24) + 1;
+ var weeknum = Math.floor((daynum-offset+7)/7);
+ if (weeknum == 0) {
+ year--;
+ var prevNewYear = new Date(year,0,1);
+ var prevOffset = 7 + 1 - prevNewYear.getDay();
+ if (prevOffset == 2 || prevOffset == 8) weeknum = 53; else weeknum = 52;
+ }
+ return weeknum;
+ },
+
+ constructCalendar : function() {
+ var aNumDays = Array (31,0,31,30,31,30,31,31,30,31,30,31)
+ var startDate = new Date (this.yearSelected,this.monthSelected,1)
+ var endDate,numDaysInMonth
+
+ if (typeof this.monthSelected!='number' || this.monthSelected>=12 || this.monthSelected<0) {
+ alert('ERROR in calendar: monthSelected='+this.monthSelected);
+ return;
+ }
+ var today = new Date();
+ this.dateNow = today.getDate();
+ this.monthNow = today.getMonth();
+ this.yearNow = today.getFullYear();
+
+ if (this.monthSelected==1) {
+ endDate = new Date (this.yearSelected,this.monthSelected+1,1);
+ endDate = new Date (endDate - (24*60*60*1000));
+ numDaysInMonth = endDate.getDate()
+ } else {
+ numDaysInMonth = aNumDays[this.monthSelected];
+ }
+ var dayPointer = startDate.getDay() - this.options.startAt
+ if (dayPointer<0) dayPointer+=7;
+ this.popDownMonth();
+
+ this.bgcolor=Element.getStyle(this.tbody,'background-color');
+ this.bgcolor=this.bgcolor.replace(/\"/g,'');
+ if (this.options.showWeekNumber) {
+ for (var i=1; i<7; i++)
+ this.tbody.rows[i].cells[0].innerHTML=' ';
+ }
+ for ( var i=1; i<=dayPointer; i++ )
+ this.resetCell(this.tbody.rows[1].cells[i]);
+
+ for ( var datePointer=1,r=1; datePointer<=numDaysInMonth; datePointer++,dayPointer++ ) {
+ var colnum=dayPointer % 7 + 1;
+ if (this.options.showWeekNumber==1 && colnum==1)
+ this.tbody.rows[r].cells[0].innerHTML=this.WeekNbr(this.yearSelected,this.monthSelected,datePointer);
+ var dateClass=this.styles[colnum];
+ if ((datePointer==this.dateNow)&&(this.monthSelected==this.monthNow)&&(this.yearSelected==this.yearNow))
+ dateClass='ricoCalToday';
+ var c=this.tbody.rows[r].cells[colnum];
+ c.innerHTML=" " + datePointer + " ";
+ c.className=dateClass;
+ var bordercolor=(datePointer==this.odateSelected) && (this.monthSelected==this.omonthSelected) && (this.yearSelected==this.oyearSelected) ? this.options.selectedDateBorder : this.bgcolor;
+ c.style.border='1px solid '+bordercolor;
+ var h=this.Holidays[this.holidayKey(this.yearSelected,this.monthSelected,datePointer)];
+ if (!h) h=this.Holidays[this.holidayKey(0,this.monthSelected,datePointer)];
+ c.style.color=h ? h.txtColor : '';
+ c.style.backgroundColor=h ? h.bgColor : '';
+ c.title=h ? h.desc : '';
+ if (colnum==7) r++;
+ }
+ while (dayPointer<42) {
+ var colnum=dayPointer % 7 + 1;
+ this.resetCell(this.tbody.rows[r].cells[colnum]);
+ dayPointer++;
+ if (colnum==7) r++;
+ }
+
+ this.titleMonth.innerHTML = RicoTranslate.monthNames[this.monthSelected].substring(0,3);
+ this.titleYear.innerHTML = this.yearSelected;
+ if (this.options.showToday)
+ this.todayCell.innerHTML=this.todayString+'<span>'+this.dateNow + " " + RicoTranslate.monthNames[this.monthNow].substring(0,3) + " " + this.yearNow+'</span>';
+ this.monthSelect.style.top=this.thead.offsetHeight+'px';
+ this.monthSelect.style.left=this.titleMonth.offsetLeft+'px';
+ },
+
+ resetCell: function(c) {
+ c.innerHTML=" ";
+ c.className='ricoCalEmpty';
+ c.style.border='1px solid '+this.bgcolor;
+ c.style.color='';
+ c.style.backgroundColor='';
+ c.title='';
+ },
+
+ saveAndClose : function(e) {
+ Event.stop(e);
+ var el=Event.element(e);
+ var s=el.innerHTML.replace(/ /g,'');
+ if (s=='' || el.className=='ricoCalWeekNum') return;
+ var day=parseInt(s);
+ if (isNaN(day)) return;
+ var d=new Date(this.yearSelected,this.monthSelected,day);
+ var dateStr=d.formatDate(this.options.dateFmt=='ISO8601' ? 'yyyy-mm-dd' : this.options.dateFmt);
+ if (this.returnValue) this.returnValue(dateStr);
+ this.close();
+ },
+
+ open : function(curval) {
+ if (!this.bPageLoaded) return;
+ if (typeof curval=='object') {
+ this.dateSelected = curval.getDate();
+ this.monthSelected = curval.getMonth();
+ this.yearSelected = curval.getFullYear();
+ } else if (this.options.dateFmt=='ISO8601') {
+ var d=new Date;
+ d.setISO8601(curval);
+ this.dateSelected = d.getDate();
+ this.monthSelected = d.getMonth();
+ this.yearSelected = d.getFullYear();
+ } else if (this.re.exec(curval)) {
+ var aDate=new Array(RegExp.$1,RegExp.$3,RegExp.$5);
+ this.dateSelected = parseInt(aDate[this.dateParts['dd']], 10);
+ this.monthSelected = parseInt(aDate[this.dateParts['mm']], 10) - 1;
+ this.yearSelected = parseInt(aDate[this.dateParts['yyyy']], 10);
+ } else {
+ if (curval) alert('ERROR: invalid date passed to calendar ('+curval+')');
+ this.dateSelected = this.dateNow
+ this.monthSelected = this.monthNow
+ this.yearSelected = this.yearNow
+ }
+ this.odateSelected=this.dateSelected
+ this.omonthSelected=this.monthSelected
+ this.oyearSelected=this.yearSelected
+ this.constructCalendar();
+ this.openPopup();
+ }
+}
+
+Rico.includeLoaded('ricoCalendar.js');
--- /dev/null
+function attachValueChangeListeners() {
+ $('red').onkeypress = colorChangedDeffered;
+ $('green').onkeypress = colorChangedDeffered;
+ $('blue').onkeypress = colorChangedDeffered;
+}
+
+function colorChangedDeffered() {
+ setTimeout( colorChanged, 1 );
+}
+
+function colorChanged() {
+ var red = Math.min( parseInt($('red').value) || 0, 255);
+ var green = Math.min( parseInt($('green').value) || 0, 255);
+ var blue = Math.min( parseInt($('blue').value) || 0, 255);
+
+ var color = new Rico.Color( red, green, blue );
+
+ var newIllustrateString = " var color = new Rico.Color( ";
+ newIllustrateString += red + ", ";
+ newIllustrateString += green + ", ";
+ newIllustrateString += blue + " ); // color.asHex() = ";
+ newIllustrateString += color.asHex();
+
+ $('rgbCode').innerHTML = newIllustrateString;
+ $('colorBox').style.backgroundColor = color.asHex();
+ //$('colorBox').innerHTML = color.asHex();
+}
+
+Rico.includeLoaded('ricoColor.js');
--- /dev/null
+// ===================================================================
+// Original author: Matt Kruse <matt@mattkruse.com>
+// WWW: http://www.mattkruse.com/
+//
+// Adapted to Rico by Matt Brown
+// ===================================================================
+
+
+Rico.ColorPicker = Class.create();
+
+Rico.ColorPicker.prototype = {
+
+ initialize: function(id,options) {
+ this.id=id;
+ this.currentValue = "#FFFFFF";
+ Object.extend(this, new Rico.Popup());
+ Object.extend(this.options, {
+ showColorCode : false,
+ cellsPerRow : 18,
+ palette : []
+ });
+ var hexvals=['00','33','66','99','CC','FF'];
+ for (var g=0; g<hexvals.length; g++)
+ for (var r=0; r<hexvals.length; r++)
+ for (var b=0; b<hexvals.length; b++)
+ this.options.palette.push(hexvals[r]+hexvals[g]+hexvals[b]);
+ Object.extend(this.options, options || {});
+ },
+
+ atLoad : function() {
+ this.container=document.createElement("div");
+ this.container.style.display="none"
+ this.container.className='ricoColorPicker';
+ var width = this.options.cellsPerRow;
+ var cp_contents = "<TABLE BORDER='1' CELLSPACING='1' CELLPADDING='0'>";
+ for (var i=0; i<this.options.palette.length; i++) {
+ if ((i % width) == 0) { cp_contents += "<TR>"; }
+ cp_contents += '<TD BGCOLOR="'+this.options.palette[i]+'"> </TD>';
+ if ( ((i+1)>=this.options.palette.length) || (((i+1) % width) == 0))
+ cp_contents += "</TR>";
+ }
+ var halfwidth = Math.floor(width/2);
+ if (this.options.showColorCode)
+ cp_contents += "<TR><TD COLSPAN='"+halfwidth+"' ID='colorPickerSelectedColor'> </TD><TD COLSPAN='"+(width-halfwidth)+"' ALIGN='CENTER' ID='colorPickerSelectedColorValue'>#FFFFFF</TD></TR>";
+ else
+ cp_contents += "<TR><TD COLSPAN='"+width+"' ID='colorPickerSelectedColor'> </TD></TR>";
+ cp_contents += "</TABLE>";
+ this.container.innerHTML=cp_contents;
+ document.body.appendChild(this.container);
+ this.setDiv(this.container);
+ this.open=this.openPopup;
+ this.close=this.closePopup;
+ Event.observe(this.container,"mouseover", this.highlightColor.bindAsEventListener(this), false);
+ Event.observe(this.container,"click", this.selectColor.bindAsEventListener(this), false);
+ this.close();
+ },
+
+ selectColor: function(e) {
+ if (this.returnValue) this.returnValue(this.currentValue);
+ this.close();
+ },
+
+ // This function runs when you move your mouse over a color block, if you have a newer browser
+ highlightColor: function(e) {
+ var elem = Event.element(e);
+ if (!elem.tagName || elem.tagName.toLowerCase() != 'td') return;
+ var c=Rico.Color.createColorFromBackground(elem).toString();
+ this.currentValue = c;
+ Element.setStyle('colorPickerSelectedColor',{'background-color':c});
+ d = $("colorPickerSelectedColorValue");
+ if (d) d.innerHTML = c;
+ }
+}
+
+Rico.includeLoaded('ricoColorPicker.js');
--- /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.
+ **/
+
+if (typeof Rico=='undefined')
+ throw("Cannot find the Rico object");
+if (typeof Prototype=='undefined')
+ throw("Rico requires the Prototype JavaScript framework");
+Rico.prototypeVersion = parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]);
+if (Rico.prototypeVersion < 1.3)
+ throw("Rico requires Prototype JavaScript framework version 1.3 or greater");
+
+/** @singleton */
+var RicoUtil = {
+
+ getDirectChildrenByTag: function(e, tagName) {
+ var kids = new Array();
+ var allKids = e.childNodes;
+ tagName=tagName.toLowerCase();
+ for( var i = 0 ; i < allKids.length ; i++ )
+ if ( allKids[i] && allKids[i].tagName && allKids[i].tagName.toLowerCase() == tagName )
+ kids.push(allKids[i]);
+ return kids;
+ },
+
+ 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;
+ },
+
+ getInnerText: function(el) {
+ if (typeof el == "string") return el;
+ if (typeof el == "undefined") { return el };
+ var cs = el.childNodes;
+ var l = cs.length;
+ var str = "";
+ for (var i = 0; i < l; i++) {
+ switch (cs[i].nodeType) {
+ case 1: //ELEMENT_NODE
+ if (Element.getStyle(cs[i],'display')=='none') continue;
+ switch (cs[i].tagName.toLowerCase()) {
+ case 'img': str += cs[i].alt || cs[i].title || cs[i].src; break;
+ case 'input': if (cs[i].type=='hidden') continue;
+ case 'select':
+ case 'textarea': str += $F(cs[i]) || ''; break;
+ default: str += this.getInnerText(cs[i]); break;
+ }
+ break;
+ case 3: //TEXT_NODE
+ str += cs[i].nodeValue;
+ break;
+ }
+ }
+ return str;
+ },
+
+ // For Konqueror 3.5, isEncoded must be true
+ getContentAsString: function( parentNode, isEncoded ) {
+ if (isEncoded) return this._getEncodedContent(parentNode);
+ if (typeof parentNode.xml != 'undefined') return this._getContentAsStringIE(parentNode);
+ return this._getContentAsStringMozilla(parentNode);
+ },
+
+ _getEncodedContent: function(parentNode) {
+ if (parentNode.innerHTML) return parentNode.innerHTML;
+ switch (parentNode.childNodes.length) {
+ case 0: return "";
+ case 1: return parentNode.firstChild.nodeValue;
+ default: return parentNode.childNodes[1].nodeValue;
+ }
+ },
+
+ _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;
+ },
+
+ docElement: function() {
+ return (document.compatMode && document.compatMode.indexOf("CSS")!=-1) ? document.documentElement : document.getElementsByTagName("body")[0];
+ },
+
+/**
+ * return available height - excludes scrollbar & margin
+ */
+ windowHeight: function() {
+ return window.innerHeight? window.innerHeight : this.docElement().clientHeight;
+ //return this.docElement().clientHeight;
+ },
+
+/**
+ * return available width - excludes scrollbar & margin
+ */
+ windowWidth: function() {
+ return this.docElement().clientWidth;
+ },
+
+ 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;
+ },
+
+ nan2zero: function(n) {
+ if (typeof(n)=='string') n=parseInt(n);
+ return isNaN(n) || typeof(n)=='undefined' ? 0 : n;
+ },
+
+ eventKey: function(e) {
+ if( typeof( e.keyCode ) == 'number' ) {
+ return e.keyCode; //DOM
+ } else if( typeof( e.which ) == 'number' ) {
+ return e.which; //NS 4 compatible
+ } else if( typeof( e.charCode ) == 'number' ) {
+ return e.charCode; //also NS 6+, Mozilla 0.9+
+ }
+ return -1; //total failure, we have no way of obtaining the key code
+ },
+
+/**
+ * Return the previous sibling that has the specified tagName
+ */
+ getPreviosSiblingByTagName: function(el,tagName) {
+ var sib=el.previousSibling;
+ while (sib) {
+ if ((sib.tagName==tagName) && (sib.style.display!='none')) return sib;
+ sib=sib.previousSibling;
+ }
+ return null;
+ },
+
+/**
+ * Return the parent HTML element that has the specified tagName.
+ * @param className optional
+ */
+ getParentByTagName: function(el,tagName,className) {
+ var par=el;
+ tagName=tagName.toLowerCase();
+ while (par) {
+ if (par.tagName && par.tagName.toLowerCase()==tagName)
+ if (!className || par.className.indexOf(className)>=0) return par;
+ par=par.parentNode;
+ }
+ return null;
+ },
+
+/**
+ * Wrap the children of a DOM element in a new element
+ * @param el the element whose children are to be wrapped
+ * @param cls class name of the wrapper (optional)
+ * @param id id of the wrapper (optional)
+ * @param wrapperTag type of wrapper element to be created (optional, defaults to DIV)
+ */
+ wrapChildren: function(el,cls,id,wrapperTag) {
+ var tag=wrapperTag || 'div';
+ var wrapper = document.createElement(tag);
+ if (id) wrapper.id=id;
+ if (cls) wrapper.className=cls;
+ while (el.firstChild)
+ wrapper.appendChild(el.firstChild);
+ el.appendChild(wrapper);
+ return wrapper;
+ },
+
+/**
+ * Format a positive number
+ * @param decPlaces the number of digits to display after the decimal point
+ * @param thouSep the character to use as the thousands separator
+ * @param decPoint the character to use as the decimal point
+ */
+ formatPosNumber: function(posnum,decPlaces,thouSep,decPoint) {
+ var a=posnum.toFixed(decPlaces).split(/\./);
+ if (thouSep) {
+ var rgx = /(\d+)(\d{3})/;
+ while (rgx.test(a[0]))
+ a[0]=a[0].replace(rgx, '$1'+thouSep+'$2');
+ }
+ return a.join(decPoint);
+ },
+
+/**
+ * Post condition - if childNodes[n] is refChild, than childNodes[n+1] is newChild.
+ */
+ DOMNode_insertAfter: function(newChild,refChild) {
+ var parentx=refChild.parentNode;
+ if(parentx.lastChild==refChild) { return parentx.appendChild(newChild);}
+ else {return parentx.insertBefore(newChild,refChild.nextSibling);}
+ },
+
+ positionCtlOverIcon: function(ctl,icon) {
+ if (ctl.style.display=='none') ctl.style.display='block';
+ var offsets=Position.page(icon);
+ var correction=Prototype.Browser.IE ? 1 : 2; // based on a 1px border
+ var lpad=this.nan2zero(Element.getStyle(icon,'padding-left'))
+ ctl.style.left = (offsets[0]+lpad+correction)+'px';
+ var scrTop=this.docScrollTop();
+ var newTop=offsets[1] + correction + scrTop;
+ var ctlht=ctl.offsetHeight;
+ var iconht=icon.offsetHeight;
+ if (newTop+iconht+ctlht < this.windowHeight()+scrTop)
+ newTop+=iconht; // display below icon
+ else
+ newTop=Math.max(newTop-ctlht,scrTop); // display above icon
+ ctl.style.top = newTop+'px';
+ },
+
+ createFormField: function(parent,elemTag,elemType,id,name) {
+ if (typeof name!='string') name=id;
+ if (Prototype.Browser.IE) {
+ // IE cannot set NAME attribute on dynamically created elements
+ var s=elemTag+' id="'+id+'"';
+ if (elemType) s+=' type="'+elemType+'"';
+ if (elemTag.match(/^(form|input|select|textarea|object|button|img)$/)) s+=' name="'+name+'"';
+ var field=document.createElement('<'+s+' />');
+ } else {
+ var field=document.createElement(elemTag);
+ if (elemType) field.type=elemType;
+ field.id=id;
+ if (typeof field.name=='string') field.name=name;
+ }
+ parent.appendChild(field);
+ return field;
+ },
+
+/**
+ * Gets the value of the specified cookie
+ */
+ getCookie: function(itemName) {
+ var arg = itemName+'=';
+ var alen = arg.length;
+ var clen = document.cookie.length;
+ var i = 0;
+ while (i < clen) {
+ var j = i + alen;
+ if (document.cookie.substring(i, j) == arg) {
+ var endstr = document.cookie.indexOf (';', j);
+ if (endstr == -1) endstr=document.cookie.length;
+ return unescape(document.cookie.substring(j, endstr));
+ }
+ i = document.cookie.indexOf(' ', i) + 1;
+ if (i == 0) break;
+ }
+ return null;
+ },
+
+/**
+ * Write information to cookie.
+ * For cookies to be retained for the current session only, set daysToKeep=null.
+ * To erase a cookie, pass a negative daysToKeep value.
+ */
+ setCookie: function(itemName,itemValue,daysToKeep,cookiePath,cookieDomain) {
+ var c = itemName+"="+escape(itemValue);
+ if (typeof(daysToKeep)=='number') {
+ var date = new Date();
+ date.setTime(date.getTime()+(daysToKeep*24*60*60*1000));
+ c+="; expires="+date.toGMTString();
+ }
+ if (typeof(cookiePath)=='string') c+="; path="+cookiePath;
+ if (typeof(cookieDomain)=='string') c+="; domain="+cookieDomain;
+ document.cookie = c;
+ }
+
+};
+
+
+// Translation helper object
+/** @singleton */
+var RicoTranslate = {
+ phrases : {},
+ thouSep : ",",
+ decPoint: ".",
+ langCode: "en",
+ re : /^(\W*)\b(.*)\b(\W*)$/,
+ dateFmt : "mm/dd/yyyy",
+ timeFmt : "hh:nn:ss a/pm",
+ monthNames: ['January','February','March','April','May','June',
+ 'July','August','September','October','November','December'],
+ dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
+
+ addPhrase: function(fromPhrase, toPhrase) {
+ this.phrases[fromPhrase]=toPhrase;
+ },
+
+/**
+ * fromPhrase may contain multiple words/phrases separated by tabs
+ * and each portion will be looked up separately.
+ * Punctuation & spaces at the beginning or
+ * ending of a phrase are ignored.
+ */
+ getPhrase: function(fromPhrase) {
+ var words=fromPhrase.split(/\t/);
+ var transWord,translated = '';
+ for (var i=0; i<words.length; i++) {
+ if (this.re.exec(words[i])) {
+ transWord=this.phrases[RegExp.$2];
+ translated += (typeof transWord=='string') ? RegExp.$1+transWord+RegExp.$3 : words[i];
+ } else {
+ translated += words[i];
+ }
+ }
+ return translated;
+ }
+}
+
+
+if (!Date.prototype.formatDate) {
+ Date.prototype.formatDate = function(fmt) {
+ var d=this;
+ var datefmt=(typeof fmt=='string') ? datefmt=fmt : 'translateDate';
+ switch (datefmt) {
+ case 'locale':
+ case 'localeDateTime':
+ return d.toLocaleString();
+ case 'localeDate':
+ return d.toLocaleDateString();
+ case 'translate':
+ case 'translateDateTime':
+ datefmt=RicoTranslate.dateFmt+' '+RicoTranslate.timeFmt;
+ break;
+ case 'translateDate':
+ datefmt=RicoTranslate.dateFmt;
+ break;
+ }
+ return datefmt.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
+ function($1) {
+ switch ($1.toLowerCase()) {
+ case 'yyyy': return d.getFullYear();
+ case 'mmmm': return RicoTranslate.monthNames[d.getMonth()];
+ case 'mmm': return RicoTranslate.monthNames[d.getMonth()].substr(0, 3);
+ case 'mm': return (d.getMonth() + 1).toPaddedString(2);
+ case 'm': return (d.getMonth() + 1);
+ case 'dddd': return RicoTranslate.dayNames[d.getDay()];
+ case 'ddd': return RicoTranslate.dayNames[d.getDay()].substr(0, 3);
+ case 'dd': return d.getDate().toPaddedString(2);
+ case 'd': return d.getDate();
+ case 'hh': return ((h = d.getHours() % 12) ? h : 12).toPaddedString(2);
+ case 'h': return ((h = d.getHours() % 12) ? h : 12);
+ case 'HH': return d.getHours().toPaddedString(2);
+ case 'H': return d.getHours();
+ case 'nn': return d.getMinutes().toPaddedString(2);
+ case 'ss': return d.getSeconds().toPaddedString(2);
+ case 'a/p': return d.getHours() < 12 ? 'a' : 'p';
+ }
+ }
+ );
+ }
+}
+
+if (!Date.prototype.setISO8601) {
+/**
+ * Converts a string in ISO 8601 format to a date object.
+ * Returns true if string is a valid date or date-time.
+ * Based on info at http://delete.me.uk/2005/03/iso8601.html
+ */
+ Date.prototype.setISO8601 = function (string) {
+ if (!string) return false;
+ var d = string.match(/(\d\d\d\d)(?:-?(\d\d)(?:-?(\d\d)(?:[T ](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|(?:([-+])(\d\d)(?::?(\d\d))?)?)?)?)?)?/);
+ if (!d) return false;
+ var offset = 0;
+ var date = new Date(d[1], 0, 1);
+
+ if (d[2]) { date.setMonth(d[2] - 1); }
+ if (d[3]) { date.setDate(d[3]); }
+ if (d[4]) { date.setHours(d[4]); }
+ if (d[5]) { date.setMinutes(d[5]); }
+ if (d[6]) { date.setSeconds(d[6]); }
+ if (d[7]) { date.setMilliseconds(Number("0." + d[7]) * 1000); }
+ if (d[8]) {
+ if (d[10] && d[11]) offset = (Number(d[10]) * 60) + Number(d[11]);
+ offset *= ((d[9] == '-') ? 1 : -1);
+ offset -= date.getTimezoneOffset();
+ }
+ var time = (Number(date) + (offset * 60 * 1000));
+ this.setTime(Number(time));
+ return true;
+ }
+}
+
+if (!Date.prototype.toISO8601String) {
+/**
+ * Convert date to an ISO 8601 formatted string.
+ * <p>format is an integer in the range 1-6:<dl>
+ * <dt>1 (year)</dt>
+ * <dd>YYYY (eg 1997)</dd>
+ * <dt>2 (year and month)</dt>
+ * <dd>YYYY-MM (eg 1997-07)</dd>
+ * <dt>3 (complete date)</dt>
+ * <dd>YYYY-MM-DD (eg 1997-07-16)</dd>
+ * <dt>4 (complete date plus hours and minutes)</dt>
+ * <dd>YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)</dd>
+ * <dt>5 (complete date plus hours, minutes and seconds)</dt>
+ * <dd>YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)</dd>
+ * <dt>6 (complete date plus hours, minutes, seconds and a decimal
+ * fraction of a second)</dt>
+ * <dd>YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)</dd>
+ *</dl>
+ * Based on: http://www.codeproject.com/jscript/dateformat.asp
+ */
+ Date.prototype.toISO8601String = function (format, offset) {
+ if (!format) { var format = 6; }
+ if (!offset) {
+ var offset = 'Z';
+ var date = this;
+ } else {
+ var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
+ var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
+ offsetnum *= ((d[1] == '-') ? -1 : 1);
+ var date = new Date(Number(Number(this) + (offsetnum * 60000)));
+ }
+
+ var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; }
+
+ var str = "";
+ str += date.getUTCFullYear();
+ if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
+ if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
+ if (format > 3) {
+ str += "T" + zeropad(date.getUTCHours()) +
+ ":" + zeropad(date.getUTCMinutes());
+ }
+ if (format > 5) {
+ var secs = Number(date.getUTCSeconds() + "." +
+ ((date.getUTCMilliseconds() < 100) ? '0' : '') +
+ zeropad(date.getUTCMilliseconds()));
+ str += ":" + zeropad(secs);
+ } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }
+
+ if (format > 3) { str += offset; }
+ return str;
+ }
+}
+
+if (!String.prototype.formatDate) {
+ String.prototype.formatDate = function(fmt) {
+ var s=this.replace(/-/g,'/');
+ var d = new Date(s);
+ return isNaN(d) ? this : d.formatDate(fmt);
+ }
+}
+
+if (!Number.prototype.formatNumber) {
+/**
+ * Format a number according to the specs in assoc array 'fmt'.
+ * Result is a string, wrapped in a span element with a class of: negNumber, zeroNumber, posNumber
+ * These classes can be set in CSS to display negative numbers in red, for example.
+ *
+ * <p>fmt may contain:<dl>
+ * <dt>multiplier </dt><dd> the original number is multiplied by this amount before formatting</dd>
+ * <dt>decPlaces </dt><dd> number of digits to the right of the decimal point</dd>
+ * <dt>decPoint </dt><dd> character to be used as the decimal point</dd>
+ * <dt>thouSep </dt><dd> character to use as the thousands separator</dd>
+ * <dt>prefix </dt><dd> string added to the beginning of the result (e.g. a currency symbol)</dd>
+ * <dt>suffix </dt><dd> string added to the end of the result (e.g. % symbol)</dd>
+ * <dt>negSign </dt><dd> specifies format for negative numbers: L=leading minus, T=trailing minus, P=parens</dd>
+ *</dl>
+ */
+ Number.prototype.formatNumber = function(fmt) {
+ if (isNaN(this)) return 'NaN';
+ var n=this;
+ if (typeof fmt.multiplier=='number') n*=fmt.multiplier;
+ var decPlaces=typeof fmt.decPlaces=='number' ? fmt.decPlaces : 0;
+ var thouSep=typeof fmt.thouSep=='string' ? fmt.thouSep : RicoTranslate.thouSep;
+ var decPoint=typeof fmt.decPoint=='string' ? fmt.decPoint : RicoTranslate.decPoint;
+ var prefix=fmt.prefix || "";
+ var suffix=fmt.suffix || "";
+ var negSign=typeof fmt.negSign=='string' ? fmt.negSign : "L";
+ negSign=negSign.toUpperCase();
+ var s,cls;
+ if (n<0.0) {
+ s=RicoUtil.formatPosNumber(-n,decPlaces,thouSep,decPoint);
+ if (negSign=="P") s="("+s+")";
+ s=prefix+s;
+ if (negSign=="L") s="-"+s;
+ if (negSign=="T") s+="-";
+ cls='negNumber';
+ } else {
+ cls=n==0.0 ? 'zeroNumber' : 'posNumber';
+ s=prefix+RicoUtil.formatPosNumber(n,decPlaces,thouSep,decPoint);
+ }
+ return "<span class='"+cls+"'>"+s+suffix+"</span>";
+ }
+}
+
+if (!String.prototype.formatNumber) {
+/**
+ * Take a string that can be converted via parseFloat
+ * and format it according to the specs in assoc array 'fmt'.
+ */
+ String.prototype.formatNumber = function(fmt) {
+ var n=parseFloat(this);
+ return isNaN(n) ? this : n.formatNumber(fmt);
+ }
+}
+
+/**
+ * Fix select control bleed-thru on floating divs in IE.
+ * Based on technique published by Joe King at:
+ * http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx
+ */
+Rico.Shim = Class.create();
+
+if (Prototype.Browser.IE) {
+ Rico.Shim.prototype = {
+
+ initialize: function(DivRef) {
+ this.ifr = document.createElement('iframe');
+ this.ifr.style.position="absolute";
+ this.ifr.style.display = "none";
+ this.ifr.src="javascript:false;";
+ DivRef.parentNode.appendChild(this.ifr);
+ this.DivRef=DivRef;
+ },
+
+ hide: function() {
+ this.ifr.style.display = "none";
+ },
+
+ show: function() {
+ this.ifr.style.width = this.DivRef.offsetWidth;
+ this.ifr.style.height = this.DivRef.offsetHeight;
+ this.ifr.style.top = this.DivRef.style.top;
+ this.ifr.style.left = this.DivRef.style.left;
+ this.ifr.style.zIndex = this.DivRef.currentStyle.zIndex - 1;
+ this.ifr.style.display = "block";
+ }
+ }
+} else {
+ Rico.Shim.prototype = {
+ initialize: function() {},
+ hide: function() {},
+ show: function() {}
+ }
+}
+
+
+/**
+ * Rico.Shadow is intended for positioned elements.
+ * Uses blur filter in IE, and alpha-transparent png images for all other browsers.
+ * Based on: http://www.positioniseverything.net/articles/dropshadows.html
+ */
+Rico.Shadow = Class.create();
+
+Rico.Shadow.prototype = {
+
+ initialize: function(DivRef) {
+ this.div = document.createElement('div');
+ this.div.style.position="absolute";
+ if (typeof this.div.style.filter=='undefined') {
+ new Image().src = Rico.imgDir+"shadow.png";
+ new Image().src = Rico.imgDir+"shadow_ur.png";
+ new Image().src = Rico.imgDir+"shadow_ll.png";
+ this.createShadow();
+ this.offset=5;
+ } else {
+ this.div.style.backgroundColor='#888';
+ this.div.style.filter='progid:DXImageTransform.Microsoft.Blur(makeShadow=1, shadowOpacity=0.3, pixelRadius=3)';
+ this.offset=0; // MS blur filter already does offset
+ }
+ this.div.style.display = "none";
+ DivRef.parentNode.appendChild(this.div);
+ this.DivRef=DivRef;
+ },
+
+ createShadow: function() {
+ var tab = document.createElement('table');
+ tab.style.height='100%';
+ tab.style.width='100%';
+ tab.cellSpacing=0;
+ tab.dir='ltr';
+
+ var tr1=tab.insertRow(-1);
+ tr1.style.height='8px';
+ var td11=tr1.insertCell(-1);
+ td11.style.width='8px';
+ var td12=tr1.insertCell(-1);
+ td12.style.background="transparent url("+Rico.imgDir+"shadow_ur.png"+") no-repeat right bottom"
+
+ var tr2=tab.insertRow(-1);
+ var td21=tr2.insertCell(-1);
+ td21.style.background="transparent url("+Rico.imgDir+"shadow_ll.png"+") no-repeat right bottom"
+ var td22=tr2.insertCell(-1);
+ td22.style.background="transparent url("+Rico.imgDir+"shadow.png"+") no-repeat right bottom"
+
+ this.div.appendChild(tab);
+ },
+
+ hide: function() {
+ this.div.style.display = "none";
+ },
+
+ show: function() {
+ this.div.style.width = this.DivRef.offsetWidth + 'px';
+ this.div.style.height= this.DivRef.offsetHeight + 'px';
+ this.div.style.top = (parseInt(this.DivRef.style.top)+this.offset)+'px';
+ this.div.style.left = (parseInt(this.DivRef.style.left)+this.offset)+'px';
+ this.div.style.zIndex= parseInt(Element.getStyle(this.DivRef,'z-index')) - 1;
+ this.div.style.display = "block";
+ }
+}
+
+
+Rico.Popup = Class.create();
+
+Rico.Popup.prototype = {
+
+ initialize: function(options,DivRef) {
+ this.options = {
+ hideOnEscape : true,
+ hideOnClick : true,
+ ignoreClicks : false,
+ position : 'absolute',
+ shadow : true
+ }
+ Object.extend(this.options, options || {});
+ if (DivRef) this.setDiv(DivRef);
+ },
+
+ setDiv: function(DivRef,closeFunc) {
+ this.divPopup=$(DivRef);
+ var position=this.options.position == 'auto' ? Element.getStyle(this.divPopup,'position').toLowerCase() : this.options.position;
+ if (!this.divPopup || position != 'absolute') return;
+ this.closeFunc=closeFunc || this.closePopup.bindAsEventListener(this);
+ this.shim=new Rico.Shim(this.divPopup);
+ if (this.options.shadow)
+ this.shadow=new Rico.Shadow(this.divPopup);
+ if (this.options.hideOnClick)
+ Event.observe(document,"click", this.closeFunc);
+ if (this.options.hideOnEscape)
+ Event.observe(document,"keyup", this._checkKey.bindAsEventListener(this));
+ if (this.options.ignoreClicks) this.ignoreClicks();
+ },
+
+ ignoreClicks: function() {
+ Event.observe(this.divPopup,"click", this._ignoreClick.bindAsEventListener(this));
+ },
+
+ _ignoreClick: function(e) {
+ if (e.stopPropagation)
+ e.stopPropagation();
+ else
+ e.cancelBubble = true;
+ return true;
+ },
+
+ // event handler to process keyup events (hide menu on escape key)
+ _checkKey: function(e) {
+ if (RicoUtil.eventKey(e)==27) this.closeFunc();
+ return true;
+ },
+
+ openPopup: function(left,top) {
+ if (typeof left=='number') this.divPopup.style.left=left+'px';
+ if (typeof top=='number') this.divPopup.style.top=top+'px';
+ this.divPopup.style.display="block";
+ if (this.shim) this.shim.show();
+ if (this.shadow) this.shadow.show();
+ },
+
+ closePopup: function() {
+ if (this.shim) this.shim.hide();
+ if (this.shadow) this.shadow.hide();
+ this.divPopup.style.display="none"
+ }
+
+}
+
+Rico.includeLoaded('ricoCommon.js');
--- /dev/null
+/**
+ * (c) 2005-2007 Richard Cowin (http://openrico.org)
+ * (c) 2005-2007 Matt Brown (http://dowdybrown.com)
+ *
+ * Rico is 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
+ **/
+
+
+Rico.ContentTransitionBase = function() {}
+Rico.ContentTransitionBase.prototype = {
+ initialize: function(titles, contents, options) {
+ if (typeof titles == 'string')
+ titles = $$(titles)
+ if (typeof contents == 'string')
+ contents = $$(contents)
+
+ this.titles = titles;
+ this.contents = contents;
+ this.options = Object.extend({
+ duration:200,
+ steps:8,
+ rate:Rico.Effect.easeIn
+ }, options || {});
+ this.hoverSet = new Rico.HoverSet(titles, options);
+ contents.each(function(p){ if (p) Element.hide(p)})
+ this.selectionSet = new Rico.SelectionSet(titles, Object.extend(this.options, {onSelect: this.select.bind(this)}));
+ if (this.initContent) this.initContent();
+ },
+ reset: function(){
+ this.selectionSet.reset();
+ },
+ select: function(title) {
+ if ( this.selected == this.contentOf(title)) return
+ var panel = this.contentOf(title);
+ if (this.transition){
+ if (this.selected){
+ var effect = this.transition(panel)
+ if (effect) Rico.animate(effect, this.options)
+ }
+ else
+ Element.show(panel);
+ }else{
+ if (this.selected)
+ Element.hide(this.selected)
+ Element.show(panel);
+ }
+ this.selected = panel;
+ },
+ add: function(title, content){
+ this.titles.push(title);
+ this.contents.push(content);
+ this.hoverSet.add(title);
+ this.selectionSet.add(title);
+ this.selectionSet.select(title);
+ },
+ remove: function(title){},
+ removeAll: function(){
+ this.hoverSet.removeAll();
+ this.selectionSet.removeAll();
+ },
+ openByIndex: function(index){this.selectionSet.selectIndex(index)},
+ contentOf: function(title){ return this.contents[this.titles.indexOf(title)]}
+}
+
+Rico.ContentTransition = Class.create();
+Rico.ContentTransition.prototype = Object.extend(new Rico.ContentTransitionBase(),{});
+
+Rico.SlidingPanel = Class.create();
+Rico.SlidingPanel.prototype = {
+ initialize: function(panel) {
+ this.panel = panel;
+ this.options = arguments[1] || {};
+ this.closed = true;
+ this.showing = false
+ this.openEffect = this.options.openEffect;
+ this.closeEffect = this.options.closeEffect;
+ this.animator = new Rico.Effect.Animator();
+ Element.makeClipping(this.panel)
+ },
+ toggle: function () {
+ if(!this.showing){
+ this.open();
+ } else {
+ this.close();
+ }
+ },
+ open: function () {
+ if (this.closed){
+ this.showing = true;
+ Element.show(this.panel);
+ this.options.disabler.disableNative();
+ }
+ /*this.animator.stop();*/
+ this.animator.play(this.openEffect,
+ { onFinish:function(){ Element.undoClipping($(this.panel))}.bind(this),
+ rate:Rico.Effect.easeIn});
+ },
+ close: function () {
+ Element.makeClipping(this.panel)
+ this.animator.stop();
+ this.showing = false;
+ this.animator.play(this.closeEffect,
+ { onFinish:function(){ Element.hide(this.panel);
+ this.options.disabler.enableNative()}.bind(this),
+ rate:Rico.Effect.easeOut});
+ }
+}
+
+
+//-------------------------------------------
+// Example components
+//-------------------------------------------
+
+Rico.Accordion = Class.create();
+Rico.Accordion.prototype = Object.extend(new Rico.ContentTransitionBase(), {
+ initContent: function() {
+ this.selected.style.height = this.options.panelHeight + "px";
+ },
+ transition: function(p){
+ if (!this.options.noAnimate)
+ return new Rico.AccordionEffect(this.selected, p, this.options.panelHeight);
+ else{
+ p.style.height = this.options.panelHeight + "px";
+ if (this.selected) Element.hide(this.selected);
+ Element.show(p);
+ }
+ }
+})
+
+
+Rico.TabbedPanel = Class.create();
+Rico.TabbedPanel.prototype = Object.extend(new Rico.ContentTransitionBase(), {
+ initContent: function() {
+ if (false && (this.options.panelHeight=='auto' || this.options.panelWidth=='auto')) {
+ // 'auto' is not working yet
+ var maxwi=0, maxht=0;
+ for (var i=0; i<this.contents.length; i++) {
+ var d=Element.getDimensions(this.contents[i]);
+ maxwi=Math.max(maxwi,d.width);
+ maxht=Math.max(maxht,d.height);
+ }
+ //alert('maxwi='+maxwi+' maxht='+maxht);
+ if (this.options.panelWidth=='auto') this.options.panelWidth=maxwi;
+ if (this.options.panelHeight=='auto') this.options.panelHeight=maxht;
+ }
+ if (typeof this.options.panelWidth=='number') this.options.panelWidth+="px";
+ if (typeof this.options.panelHeight=='number') this.options.panelHeight+="px";
+ if (Rico.Corner) {
+ this.options.color='transparent';
+ this.options.corners='top';
+ for (var i=0; i<this.titles.length; i++)
+ if (this.titles[i]) {
+ if (this.options.panelHdrWidth) this.titles[i].style.width=this.options.panelHdrWidth;
+ Rico.Corner.round(this.titles[i], this.options);
+ }
+ }
+ this.transition(this.selected);
+ },
+ transition: function(p){
+ if (this.selected) Element.hide(this.selected);
+ Element.show(p);
+ if (this.options.panelHeight) p.style.height = this.options.panelHeight;
+ if (this.options.panelWidth) p.style.width = this.options.panelWidth;
+ }
+})
+
+
+Rico.SlidingPanel.top = function(panel, innerPanel){
+ var options = Object.extend({
+ disabler: Rico.Controls.defaultDisabler
+ }, arguments[2] || {});
+ var height = options.height || Element.getDimensions(innerPanel)[1] || innerPanel.offsetHeight;
+ var top = options.top || Position.positionedOffset(panel)[1];
+ options.openEffect = new Rico.Effect.SizeFromTop(panel, innerPanel, top, height, {baseHeight:height});
+ options.closeEffect = new Rico.Effect.SizeFromTop(panel, innerPanel, top, 1, {baseHeight:height});
+ panel.style.height = "0px";
+ innerPanel.style.top = -height + "px";
+ return new Rico.SlidingPanel(panel, options);
+}
+
+Rico.SlidingPanel.bottom = function(panel){
+ var options = Object.extend({
+ disabler: Rico.Controls.blankDisabler
+ }, arguments[1] || {});
+ var height = options.height || Element.getDimensions(panel).height;
+ var top = Position.positionedOffset(panel)[1];
+ options.openEffect = new Rico.Effect.SizeFromBottom(panel, top - height, height);
+ options.closeEffect = new Rico.Effect.SizeFromBottom(panel, top, 1);
+ return new Rico.SlidingPanel(panel, options);
+}
+
+Rico.includeLoaded('ricoComponents.js');
--- /dev/null
+
+Rico.Dashboard = Class.create();
+Rico.Dashboard.prototype = {
+ initialize: function(dashboardId, columnCount, options) {
+ this.dashboardDiv = $(dashboardId);
+ this.numCol = columnCount;
+ this.options = options || [];
+ this.cols = new Array();
+ this.insertionOutline = document.createElement("div");
+ this.insertionOutline.id = "insertionOutline";
+
+ //get panels before adding collumns
+ var dashboard = this
+ this.panelList = [];
+ // this.panelList = parsePanels(this.dashboardDiv, function(title, content, panel)
+ // { return new Rico.DashboardPanel(title, content, panel, dashboard);})
+ var colSizes = this.options.columnSizes
+ if (!colSizes){
+ colSizes = [];
+ for(var i=0; i<this.numCol; i++)
+ colSizes[i] = 100 / columnCount;
+ }
+
+ for(var i=0; i< this.numCol;i++) {
+ var newColDiv = document.createElement("div");
+ newColDiv.style.width = colSizes[i] + "%";
+ newColDiv.style.minHeight = "1px";
+ newColDiv.className = "column";
+ newColDiv.id = "" + (i+1) ;
+ this.cols.push(newColDiv);
+ this.dashboardDiv.appendChild(newColDiv);
+ //if (i < this.numCol-1){
+ // var borderDiv = document.createElement("div");
+ // borderDiv.style.width = "3px";
+ // borderDiv.style.height = "100%";
+ // borderDiv.style.background = "111111"
+ // borderDiv.className = "border";
+ // //borderDiv.style.visibility = "visible";
+ // this.dashboardDiv.appendChild(borderDiv);
+ // }
+ }
+ //now add the panels to the columns
+ for (var i=0; i< this.panelList.length; i++) {
+ var panel = this.panelList[i];
+ this._addToCol(panel, panel.panelDiv.getAttribute('column'));
+ }
+ },
+
+ addPanel: function(panel, col){
+ this.panelList.push(panel)
+ this._addToCol(panel, col)
+ },
+
+ _addToCol: function(panel, col) {
+ panel.addToCol(this.cols[col-1]);
+ },
+
+ closeAllPanels: function() {
+ var panels = this.panelList;
+ for (var i=0; i<panels.length; i++)
+ panels[i].close();
+ this.panelList = [];
+ },
+
+ openAllPanels: function(open) {
+ for (var i=0; i<this.panelList.length; i++)
+ this.panelList[i].setVisibility(open);
+ },
+
+ columnAt: function(x) {
+ for (var i=this.cols.length-1; i >=0; i--) {
+ if (x >= Position.positionedOffset(this.cols[i])[0])
+ return this.cols[i];
+ }
+ return this.cols[0];
+ },
+
+ destroy: function() {
+ try{
+ for (var i=0; i<this.panelList.length; i++) {
+ delete this.panelList[i];
+ this.panelList[i] = null;
+ }
+ delete this;
+ }catch(e){}
+ },
+
+ dropPanel: function(panel){
+ panel.column.removeChild(panel.panelDiv);
+ panel.column = this.insertionColumn;
+ this.insertionColumn.replaceChild(panel.panelDiv, this.insertionOutline);
+ },
+
+ dragPanel: function(panel, left, top){
+ var newCol = this.columnAt(left + panel.panelDiv.offsetWidth/2);
+
+ if (!newCol) return;
+
+ this._moveInsertion(newCol);
+ var panels = this.columnPanels(newCol);
+ var insertPos = this._getInsertionPos(panels);
+
+ if (insertPos != 0 &&
+ top <= Position.positionedOffset(panels[insertPos-1])[1]) {
+ this.insertionColumn.removeChild(this.insertionOutline);
+ newCol.insertBefore(this.insertionOutline, panels[insertPos-1]);
+ }
+ if (insertPos != (panels.length-1) &&
+ top >= Position.positionedOffset(panels[insertPos+1])[1]) {
+ if (panels[insertPos + 2])
+ newCol.insertBefore(this.insertionOutline, panels[insertPos+2]);
+ else
+ newCol.appendChild(this.insertionOutline);
+ }
+ this.insertionColumn = newCol;
+ },
+
+ _moveInsertion: function(column){
+ if (this.insertionColumn != column) {
+ this.insertionColumn.removeChild(this.insertionOutline)
+ this.insertionColumn = column;
+ column.appendChild(this.insertionOutline);
+ }
+ },
+
+ columnPanels: function(column){
+ var panels = [];
+ for (var i=0; i<column.childNodes.length; i++) {
+ if (!column.childNodes[i].isDragging) {
+ panels.push(column.childNodes[i]);
+ }
+ }
+ return panels;
+ },
+
+ _getInsertionPos : function(panels) {
+ for (var i=0; i<panels.length; i++) {
+ if (panels[i] == this.insertionOutline)
+ return i;
+ }
+ },
+
+ startInsertionOutline: function(panelDiv){
+ this.insertionOutline.style.height = panelDiv.offsetHeight + "px";
+ panelDiv.parentNode.insertBefore(this.insertionOutline, panelDiv);
+ this.insertionColumn = panelDiv.parentNode;
+ }
+}
+
+Rico.PanelCreation = {
+ create: function(title, url, dashboard) {
+ var panelDiv = document.createElement("div");
+ var titleDiv = PanelCreation.createHeader(title)
+ var contentDiv = PanelCreation.createContent()
+ panelDiv.className = "panel";
+ panelDiv.appendChild(titleDiv);
+ panelDiv.appendChild(contentDiv);
+ return new Rico.DashboardPanel(titleDiv, contentDiv, panelDiv, dashboard)
+ },
+ createHeader: function(title) {
+ this.panelHeaderDiv = document.createElement("div");
+ this.panelHeaderDiv.className = "panelHeader";
+ this.panelHeaderDiv.innerHTML = document.createTextNode(this.title);
+ initializeHeader(this.panelHeaderDiv);
+ return this.panelHeaderDiv;
+ },
+ createContent: function() {
+ this.panelContentDiv = document.createElement("div");
+ this.panelContentDiv.className = "panelContent";
+ this.panelContentDiv.innerHTML = "Loading";
+ return this.panelContentDiv;
+ }
+}
+
+Rico.DashboardPanel = Class.create();
+Rico.DashboardPanel.prototype = {
+ initialize: function(headerDiv, contentDiv, panelDiv, dashboard) {
+ this.dashboard = dashboard;
+ this.panelHeaderDiv = headerDiv;
+ this.panelContentDiv = contentDiv;
+ this.panelDiv = panelDiv;
+ this.open = true;
+ panelDiv.style.zIndex = 1000;
+ this.initializeHeader(headerDiv);
+ Event.observe(headerDiv, "mousedown", this._startDrag.bind(this));
+ },
+
+ initializeHeader: function(headerDiv) {
+ headerDiv.onmouseover = this.hover.bind(this);
+ headerDiv.onmouseout = this.unHover.bind(this);
+
+// this.visibilityToggleDiv = document.createElement("div");
+// this.visibilityToggleDiv.className = "visibilityToggle";
+// this.visibilityToggleDiv.innerHTML = '<img src="/images/bkgd_panel_arrow.png"/>';
+// this.visibilityToggleDiv.style.visibility = "hidden";
+// this.visibilityToggleDiv.onmousedown = this.toggleVisibility.bind(this);
+
+ this.titleDiv = document.createElement("div");
+ this.titleDiv.innerHTML = headerDiv.innerHTML;
+ this.titleDiv.className = "title";
+
+ headerDiv.innerHTML = '';
+
+ this.closeDiv = document.createElement("div");
+ this.closeDiv.className = "close";
+ this.closeDiv.innerHTML = '<img src="/images/icn_close.png" alt="Remove" title="Remove this metric from the report" />';
+ this.closeDiv.style.display = "none";
+ this.closeDiv.onmousedown = this.close.bind(this);
+
+// headerDiv.appendChild(this.visibilityToggleDiv);
+ headerDiv.appendChild(this.closeDiv);
+ headerDiv.appendChild(this.titleDiv);
+ },
+
+ addToCol: function(col, isNew) {
+ this.column = col;
+ if (isNew && toCol.hasChildNodes())
+ this.column.insertBefore(this.panelDiv, this.column.firstChild);
+ else
+ this.column.appendChild(this.panelDiv);
+ },
+
+ moveToColumn: function(col){
+ if (this.column != col) {
+ this.column.removeChild(this.panelDiv)
+ this.column = col;
+ col.appendChild(this.panelDiv);
+ }
+ },
+ //this.obj.root.onDragStart(parseInt(panel.panelDiv.style.left), parseInt(pnel.panelDiv.style.top),
+ // event.clientX, event.clientY);
+ _startDrag: function(event) {
+ if (this.dashboard.options.startingDrag)
+ this.dashboard.options.startingDrag();
+
+ Position.absolutize(this.panelDiv)
+ this.dashboard.startInsertionOutline(this.panelDiv)
+ this.panelDiv.style.opacity = .7;
+ this.panelDiv.style.zIndex = 900;
+ //this.panelDiv.style.width = (parseInt(this.panelDiv.offestWidth)-4)+"px";
+ new DragPanel(this, event);
+ Event.stop(event);
+ },
+
+ hover: function() {
+// this.visibilityToggleDiv.style.visibility = "visible";
+ this.closeDiv.show();
+ },
+
+ unHover: function() {
+// this.visibilityToggleDiv.style.visibility = "hidden";
+ this.closeDiv.hide();
+ },
+
+ setVisibility: function(visibility) {
+ if (visibility) {
+ this.panelDiv.show();
+ } else {
+ this.panelDiv.hide();
+ }
+ },
+
+ toggleVisibility: function() {
+ this.setVisibility(this.panelContentDiv.style.display =='none');
+ },
+
+ close: function() {
+ if (this.open)
+ this.panelDiv.parentNode.removeChild(this.panelDiv);
+ this.open = false;
+ },
+
+ show: function() {
+ this.panelContentDiv.show();
+ this.visibilityToggleDiv.firstChild.setAttribute("src", "/images/bkgd_panel_arrow.png");
+ },
+
+ hide: function() {
+ this.panelContentDiv.hide();
+ this.visibilityToggleDiv.firstChild.setAttribute("src", "/images/bkgd_panel_arrow.png");
+ },
+
+ drop: function() {
+ this.dashboard.dropPanel(this);
+
+ this.panelDiv.style.position = "static";
+ //this.panelDiv.style.width = "100%";
+ this.unHover();
+ this.panelDiv.style.opacity = 1;
+ if (this.dashboard.options.endingDrag)
+ this.dashboard.options.endingDrag();
+ }
+}
+
+DragPanel = Class.create();
+DragPanel.prototype = {
+ initialize : function(panel,event){
+ this.panel = panel;
+ this.lastMouseX = event.clientX;
+ this.lastMouseY = event.clientY;
+ this.dragHandler = this.drag.bindAsEventListener(this)
+ this.dropHandler = this.endDrag.bindAsEventListener(this)
+ Event.observe(document, "mousemove", this.dragHandler);
+ Event.observe(document, "mouseup", this.dropHandler);
+ this.panel.panelDiv.isDragging = true
+ },
+ drag : function(event){
+
+ panelDiv = this.panel.panelDiv
+ var newLeft = parseInt(panelDiv.style.left) + event.clientX - this.lastMouseX;
+ var newTop = parseInt(panelDiv.style.top) + event.clientY - this.lastMouseY;
+ panelDiv.style.left = newLeft + "px";
+ panelDiv.style.top = newTop + "px";
+ this.lastMouseX = event.clientX;
+ this.lastMouseY = event.clientY;
+ this.panel.dashboard.dragPanel(this.panel, newLeft, newTop);
+ Event.stop(event);
+ },
+ endDrag : function(event){
+ Event.stopObserving(document, "mousemove", this.dragHandler);
+ Event.stopObserving(document, "mouseup", this.dropHandler);
+ this.panel.drop();
+ this.panel.panelDiv.style.zIndex = 1000;
+ this.panel.panelDiv.isDragging = false;
+ Event.stop(event);
+ }
+}
+
+Rico.includeLoaded('ricoDashboard.js');
--- /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.
+ **/
+//-------------------- 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" )
+/* if (Element.getStyle(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);
+ Rico.animate(new Rico.Effect.Position( this.dragElement, this.origPos.x, this.origPos.y),
+ {duration: 200,
+ steps: 20,
+ onFinish : 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");
+// this.saveBackground = Element.getStyle(htmlElement,'backgroundColor') || Element.getStyle(htmlElement,'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 (Element.getStyle(theGUI,'position')=='absolute')*/
+ if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
+ {
+ theGUI.style.position = "static";
+ theGUI.style.top = "";
+ theGUI.style.top = "";
+ }
+ htmlElement.appendChild(theGUI);
+ }
+ }
+}
+
+RicoUtil = Object.extend(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;
+ }
+});
+
+Rico.includeLoaded('ricoDragDrop.js');
--- /dev/null
+ /**
+ * (c) 2005-2007 Richard Cowin (http://openrico.org)
+ *
+ * Rico is 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
+ **/
+
+Rico.animate = function(effect){
+ new Rico.Effect.Animator().play(effect, arguments[1]);
+}
+
+Rico.Effect = {}
+Rico.Effect.easeIn = function(step){
+ return Math.sqrt(step)
+}
+Rico.Effect.easeOut = function(step){
+ return step*step
+}
+Rico.Stepping = {}
+Rico.Stepping.easeIn = Rico.Effect.easeIn;
+Rico.Stepping.easeOut = Rico.Effect.easeOut;
+
+Rico.Effect.Animator = Class.create();
+Rico.Effect.Animator.prototype = {
+ initialize : function(effect) {
+ this.animateMethod = this.animate.bind(this);
+ this.options = arguments[1] || {};
+ this.stepsLeft = 0;
+ if (!effect) return;
+ this.reset(effect, arguments[1]);
+ },
+ reset: function(effect){
+ this.effect = effect;
+ if (arguments[1]) this.setOptions(arguments[1]);
+ this.stepsLeft = this.options.steps;
+ this.duration = this.options.duration;
+ },
+ setOptions: function(options){
+ this.options = Object.extend({
+ steps: 10,
+ duration: 200,
+ rate: function(steps){ return steps;}
+ }, options|| {});
+ },
+ play: function(effect) {
+ this.setOptions(arguments[1])
+ if (effect)
+ if (effect.step)
+ this.reset(effect, arguments[1]);
+ else{
+ $H(effect).keys().each((function(e){
+ var effectClass = {fadeOut:Rico.Effect.FadeOut}[e];
+ this.reset(new effectClass(effect[e]));
+ }).bind(this))
+ }
+ this.animate();
+ },
+ stop: function() {
+ this.stepsLeft = this.options.steps;
+ },
+ pause: function() {
+ this.interupt = true;
+ },
+ resume: function() {
+ this.interupt = false;
+ if (this.stepsLeft >0)
+ this.animate();
+ },
+ animate: function() {
+ if (this.interupt)
+ return;
+ if (this.stepsLeft <=0) {
+ if (this.effect.finish) this.effect.finish();
+ if (this.options.onFinish) this.options.onFinish();
+ return;
+ }
+ if (this.timer)
+ clearTimeout(this.timer);
+ this.effect.step(this.options.rate(this.stepsLeft));
+ this.startNextStep();
+ },
+ startNextStep: function() {
+ var stepDuration = Math.round(this.duration/this.stepsLeft) ;
+ this.duration -= stepDuration;
+ this.stepsLeft--;
+ this.timer = setTimeout(this.animateMethod, stepDuration);
+ },
+ isPlaying: function(){
+ return this.stepsLeft != 0 && !this.interupt;
+ }
+}
+
+Rico.Effect.Group = Class.create();
+Rico.Effect.Group.prototype = {
+ initialize: function(effects){
+ this.effects = effects;
+ },
+ step: function(stepsToGo){
+ this.effects.each(function(e){e.step(stepsToGo)});
+ },
+ finish: function(){
+ this.effects.each(function(e){if (e.finish) e.finish()});
+ }
+}
+
+Rico.Effect.SizeAndPosition = Class.create();
+Rico.Effect.SizeAndPosition.prototype = {
+ initialize: function(element, x, y, w, h) {
+ this.element = $(element);
+ this.x = x || this.element.offsetLeft;
+ this.y = y || this.element.offsetTop;
+ this.w = w || this.element.offsetWidth;
+ this.h = h || this.element.offsetHeight;
+ },
+ step: function(stepsToGo) {
+ var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px"
+ var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/stepsToGo) + "px"
+ var width = this.element.offsetWidth + ((this.w - this.element.offsetWidth)/stepsToGo) + "px"
+ var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/stepsToGo) + "px"
+ var style = this.element.style;
+ style.left = left;
+ style.top = top;
+ style.width = width;
+ style.height = height;
+ }
+}
+
+Rico.AccordionEffect = Class.create();
+Rico.AccordionEffect.prototype = {
+ initialize: function(toClose, toOpen, height) {
+ this.toClose = toClose;
+ this.toOpen = toOpen;
+/* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/
+ Element.makeClipping(toOpen);
+ Element.makeClipping(toClose);
+/* }*/
+ Rico.Controls.disableNativeControls(toClose);
+ Element.show(toOpen);
+ this.toOpen.style.height = "0px";
+ this.endHeight = height;
+ },
+ step: function(framesLeft) {
+ var cHeight = Math.max(1,this.toClose.offsetHeight - parseInt((parseInt(this.toClose.offsetHeight))/framesLeft));
+ var closeHeight = cHeight + "px";
+ var openHeight = (this.endHeight - cHeight) + "px"
+ this.toClose.style.height = closeHeight;
+ this.toOpen.style.height = openHeight;
+ },
+ finish: function(){
+ Element.hide(this.toClose)
+ this.toOpen.style.height = this.endHeight + "px";
+ this.toClose.style.height = "0px";
+/* if (!navigator.appVersion.match(/\bMSIE\b/)) {*/
+ Element.undoClipping(this.toOpen);
+ Element.undoClipping(this.toClose);
+/* }*/
+
+ Rico.Controls.enableNativeControls(this.toOpen);
+ }
+};
+
+Rico.Effect.SizeFromBottom = Class.create()
+Rico.Effect.SizeFromBottom.prototype = {
+ initialize: function(element, y, h) {
+ this.element = $(element);
+ this.y = y || this.element.offsetTop;
+ this.h = h || this.element.offsetHeight;
+ this.options = arguments[3] || {};
+ },
+ step: function(framesToGo) {
+ var top = this.element.offsetTop + ((this.y - this.element.offsetTop)/framesToGo) + "px"
+ var height = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo) + "px"
+ var style = this.element.style;
+ style.height = height;
+ style.top = top;
+ }
+}
+
+Rico.Effect.Position = Class.create();
+Rico.Effect.Position.prototype = {
+ initialize: function(element, x, y) {
+ this.element = $(element);
+ this.x = x || this.element.offsetLeft;
+ this.destTop = y || this.element.offsetTop;
+ },
+ step: function(stepsToGo) {
+ var left = this.element.offsetLeft + ((this.x - this.element.offsetLeft)/stepsToGo) + "px"
+ var top = this.element.offsetTop + ((this.destTop - this.element.offsetTop)/stepsToGo) + "px"
+ var style = this.element.style;
+ style.left = left;
+ style.top = top;
+ }
+}
+
+Rico.Effect.FadeTo = Class.create()
+Rico.Effect.FadeTo.prototype = {
+ initialize: function(element, value){
+ this.element = element;
+ this.opacity = Element.getStyle(this.element, 'opacity') || 1.0;
+ this.target = Math.min(value, 1.0);
+ },
+ step: function(framesLeft) {
+ var curOpacity = Element.getStyle(this.element, 'opacity');
+ var newOpacity = curOpacity + (this.target - curOpacity)/framesLeft
+ Rico.Effect.setOpacity(this.element, Math.min(Math.max(0,newOpacity),1.0));
+ }
+}
+
+Rico.Effect.FadeOut = Class.create()
+Rico.Effect.FadeOut.prototype = {
+ initialize: function(element){
+ this.effect = new Rico.Effect.FadeTo(element, 0.0)
+ },
+ step: function(framesLeft) {
+ this.effect.step(framesLeft);
+ }
+}
+
+Rico.Effect.FadeIn = Class.create()
+Rico.Effect.FadeIn.prototype = {
+ initialize: function(element){
+ var options = arguments[1] || {}
+ var startValue = options.startValue || 0
+ Element.setStyle(element, 'opacity', startValue);
+ this.effect = new Rico.Effect.FadeTo(element, 1.0)
+ },
+ step: function(framesLeft) {
+ this.effect.step(framesLeft);
+ }
+}
+
+Rico.Effect.setOpacity= function(element, value) {
+ element.style.filter = "alpha(opacity:"+Math.round(value*100)+")";
+ element.style.opacity = value;
+}
+
+Rico.Effect.SizeFromTop = Class.create()
+Rico.Effect.SizeFromTop.prototype = {
+ initialize: function(element, scrollElement, y, h) {
+ this.element = $(element);
+ this.h = h || this.element.offsetHeight;
+ // element.style.top = y;
+ this.scrollElement = scrollElement;
+ this.options = arguments[4] || {};
+ this.baseHeight = this.options.baseHeight || Math.max(this.h, this.element.offsetHeight)
+ },
+ step: function(framesToGo) {
+ var rawHeight = this.element.offsetHeight + ((this.h - this.element.offsetHeight)/framesToGo);
+ var height = rawHeight + "px"
+ var scroll = (rawHeight - this.baseHeight) + "px";
+ this.scrollElement.style.top = scroll;
+ this.element.style.height = height;
+ }
+}
+
+
+Rico.Effect.Height = Class.create()
+Rico.Effect.Height.prototype = {
+ initialize: function(element, endHeight) {
+ this.element = element
+ this.endHeight = endHeight
+ },
+ step: function(stepsLeft) {
+ if (this.element.constructor != Array){
+ var height = this.element.offsetHeight + ((this.endHeight - this.element.offsetHeight)/stepsLeft) + "px"
+ this.element.style.height = height;
+ } else {
+ var height = this.element[0].offsetHeight + ((this.endHeight - this.element[0].offsetHeight)/stepsLeft) + "px"
+ this.element.each(function(e){e.style.height = height})
+ }
+ }
+}
+
+Rico.Effect.SizeWidth = Class.create();
+Rico.Effect.SizeWidth.prototype = {
+ initialize: function(element, endWidth) {
+ this.element = element
+ this.endWidth = endWidth
+ },
+ step: function(stepsLeft) {
+ delta = Math.abs(this.endWidth - parseInt(this.element.offsetWidth))/(stepsLeft);
+ this.element.style.width = (this.element.offsetWidth - delta) + "px";
+ }
+}
+
+//these are to support non Safari browsers and keep controls from bleeding through on absolute positioned element.
+Rico.Controls = {
+ editors: [],
+ scrollSelectors: [],
+
+ disableNativeControls: function(element) {
+ Rico.Controls.defaultDisabler.disableNative(element);
+ },
+ enableNativeControls: function(element){
+ Rico.Controls.defaultDisabler.enableNative(element);
+ },
+ prepareForSizing: function(element){
+ Element.makeClipping(element)
+ Rico.Controls.disableNativeControls(element)
+ },
+ resetSizing: function(element){
+ Element.undoClipping(element)
+ Rico.Controls.enableNativeControls(element)
+ },
+ registerScrollSelectors: function(selectorSet) {
+ selectorSet.each(function(s){Rico.Controls.scrollSelectors.push(Rico.selector(s))});
+ }
+}
+
+Rico.Controls.Disabler = Class.create();
+Rico.Controls.Disabler.prototype = {
+ initialize: function(){
+ this.options = Object.extend({
+ excludeSet: [],
+ hidables: Rico.Controls.editors
+ }, arguments[0] || {});
+ },
+ disableNative: function(element) {
+ if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){
+ if (!navigator.appVersion.match(/\bMSIE\b/))
+ this.blockControls(element).each(function(e){Element.makeClipping(e)});
+ else
+ this.hidableControls(element).each(function(e){e.disable()});
+ }
+ },
+ enableNative: function(element){
+ if (!(/Konqueror|Safari|KHTML/.test(navigator.userAgent))){
+ if (!navigator.appVersion.match(/\bMSIE\b/))
+ this.blockControls(element).each(function(e){Element.undoClipping(e)});
+ else
+ this.hidableControls(element).each(function(e){e.enable()});
+ }
+ },
+ blockControls: function(element){
+ try{
+ var includes = [];
+ if (this.options.includeSet)
+ includes = this.options.includeSet;
+ else{
+ var selectors = this.options.includeSelectors || Rico.Controls.scrollSelectors;
+ includes = selectors.map(function(s){return s.findAll(element)}).flatten();
+ }
+ return includes.select(function(e){return (Element.getStyle(e, 'display') != 'none') && !this.options.excludeSet.include(e)}.bind(this));
+ }catch(e) { return []}
+ },
+ hidableControls: function(element){
+ if (element)
+ return this.options.hidables.select(function(e){return Element.childOf(e, element)});
+ else
+ return this.options.hidables;
+ }
+}
+
+Rico.Controls.defaultDisabler = new Rico.Controls.Disabler();
+Rico.Controls.blankDisabler = new Rico.Controls.Disabler({includeSet:[],hidables:[]});
+
+Rico.Controls.HidableInput = Class.create();
+Rico.Controls.HidableInput.prototype = {
+ initialize: function(field, view){
+ this.field = field;
+ this.view = view;
+ this.enable();
+ Rico.Controls.editors.push(this);
+ },
+ enable: function(){
+ Element.hide(this.view);
+ Element.show(this.field);
+ },
+ disable: function(){
+ this.view.value = $F(this.field);
+ if (this.field.offsetWidth > 1) {
+ this.view.style.width = parseInt(this.field.offsetWidth) + "px";
+ Element.hide(this.field);
+ Element.show(this.view);
+ }
+ }
+}
+
+
+
+Element.forceRefresh = function(item) {
+ try {
+ var n = document.createTextNode(' ')
+ item.appendChild(n); item.removeChild(n);
+ } catch(e) { }
+};
+
+Rico.includeLoaded('ricoEffects.js');
--- /dev/null
+/**
+ * (c) 2005-2007 Richard Cowin (http://openrico.org)
+ * (c) 2005-2007 Matt Brown (http://dowdybrown.com)
+ *
+ * Rico is 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
+ **/
+
+
+if(typeof Rico=='undefined') throw("GridCommon requires the Rico JavaScript framework");
+if(typeof RicoUtil=='undefined') throw("GridCommon requires the RicoUtil Library");
+
+
+/**
+ * Define methods that are common to both SimpleGrid and LiveGrid
+ */
+Rico.GridCommon = function() {};
+
+Rico.GridCommon.prototype = {
+
+ baseInit: function() {
+ this.options = {
+ resizeBackground : 'resize.gif',
+ saveColumnInfo : {width:true, filter:false, sort:false}, // save info in cookies?
+ allowColResize : true, // allow user to resize columns
+ windowResize : true, // Resize grid on window.resize event? Set to false when embedded in an accordian.
+ click : null,
+ dblclick : null,
+ contextmenu : null,
+ useUnformattedColWidth : true,
+ menuEvent : 'dblclick', // event that triggers menus - click, dblclick, contextmenu, or none (no menus)
+ defaultWidth : 100, // in the absence of any other width info, columns will be this many pixels wide
+ scrollBarWidth : 19, // this is the value used in positioning calculations, it does not actually change the width of the scrollbar
+ minScrollWidth : 100, // min scroll area width when width of frozen columns exceeds window width
+ columnSpecs : []
+ }
+ this.colWidths = new Array();
+ this.hdrCells=new Array();
+ this.headerColCnt=0;
+ this.headerRowIdx=0;
+ this.tabs=new Array(2);
+ this.thead=new Array(2);
+ this.tbody=new Array(2);
+ },
+
+ attachMenuEvents: function() {
+ if (!this.options.menuEvent || this.options.menuEvent=='none') return;
+ this.hideScroll=navigator.userAgent.match(/Macintosh\b.*\b(Firefox|Camino)\b/i) || Prototype.Browser.Opera;
+ this.options[this.options.menuEvent]=this.handleMenuClick.bindAsEventListener(this);
+ if (this.highlightDiv) {
+ switch (this.options.highlightElem) {
+ case 'cursorRow':
+ this.attachMenu(this.highlightDiv);
+ break;
+ case 'cursorCell':
+ for (var i=0; i<2; i++)
+ this.attachMenu(this.highlightDiv[i]);
+ break;
+ }
+ }
+ for (var i=0; i<2; i++)
+ this.attachMenu(this.tbody[i]);
+ },
+
+ attachMenu: function(elem) {
+ if (this.options.click)
+ Event.observe(elem, 'click', this.options.click, false);
+ if (this.options.dblclick) {
+ if (Prototype.Browser.WebKit || Prototype.Browser.Opera)
+ Event.observe(elem, 'click', this.handleDblClick.bindAsEventListener(this), false);
+ else
+ Event.observe(elem, 'dblclick', this.options.dblclick, false);
+ }
+ if (this.options.contextmenu) {
+ if (Prototype.Browser.Opera)
+ Event.observe(elem, 'click', this.handleContextMenu.bindAsEventListener(this), false);
+ else
+ Event.observe(elem, 'contextmenu', this.options.contextmenu, false);
+ }
+ },
+
+ // implement double-click for browsers that don't support a double-click event (e.g. Safari)
+ handleDblClick: function(e) {
+ var elem=Event.element(e);
+ if (this.dblClickElem == elem) {
+ this.options.dblclick(e);
+ } else {
+ this.dblClickElem = elem;
+ this.safariTimer=setTimeout(this.clearDblClick.bind(this),300);
+ }
+ },
+
+ clearDblClick: function() {
+ this.dblClickElem=null;
+ },
+
+ // implement right-click for browsers that don't support contextmenu event (e.g. Opera)
+ // use control-click instead
+ handleContextMenu: function(e) {
+ if( typeof( e.which ) == 'number' )
+ var b = e.which; //Netscape compatible
+ else if( typeof( e.button ) == 'number' )
+ var b = e.button; //DOM
+ else
+ return;
+ if (b==1 && e.ctrlKey)
+ this.options.contextmenu(e);
+ },
+
+ cancelMenu: function() {
+ if (this.menu && this.menu.isVisible()) this.menu.cancelmenu();
+ },
+
+ // gather info from original headings
+ getColumnInfo: function(hdrSrc) {
+ Rico.writeDebugMsg("getColumnInfo start");
+ //alert(hdrSrc.tagName+' '+hdrSrc.id+' len='+hdrSrc.length);
+ if (hdrSrc.length == 0) return;
+ this.headerRowCnt=hdrSrc.length;
+ var colcnt;
+ for (r=0; r<this.headerRowCnt; r++) {
+ var headerRow = hdrSrc[r];
+ var headerCells=headerRow.cells;
+ if (r >= this.hdrCells.length) this.hdrCells[r]=new Array();
+ for (c=0; c<headerCells.length; c++) {
+ var obj={};
+ obj.cell=headerCells[c];
+ obj.colSpan=headerCells[c].colSpan || 1; // Safari & Konqueror return default colspan of 0
+ if (this.options.useUnformattedColWidth) obj.initWidth=headerCells[c].offsetWidth
+ this.hdrCells[r].push(obj);
+ }
+ if (headerRow.id.slice(-5)=='_main') {
+ colcnt=this.hdrCells[r].length;
+ this.headerRowIdx=r;
+ }
+ }
+ Rico.writeDebugMsg("getColumnInfo end");
+ if (!colcnt) {
+ this.headerRowIdx=this.headerRowCnt-1;
+ colcnt=this.hdrCells[this.headerRowIdx].length
+ }
+ return colcnt;
+ },
+
+ // create column array
+ createColumnArray: function() {
+ this.direction=Element.getStyle(this.outerDiv,'direction').toLowerCase(); // ltr or rtl
+ this.align=this.direction=='rtl' ? ['right','left'] : ['left','right'];
+ //alert(this.direction+' : '+this.align[0]);
+ this.columns = new Array();
+ for (var c=0 ; c < this.headerColCnt; c++) {
+ Rico.writeDebugMsg("createColumnArray: c="+c);
+ var tabidx=c<this.options.frozenColumns ? 0 : 1;
+ this.columns.push(new Rico.TableColumn(this, c, this.hdrCells[this.headerRowIdx][c], tabidx));
+ }
+ this.getCookie();
+ },
+
+ // create div structure
+ createDivs: function() {
+ Rico.writeDebugMsg("createDivs start");
+ this.outerDiv = this.createDiv("outer");
+ this.scrollDiv = this.createDiv("scroll",this.outerDiv);
+ this.frozenTabs = this.createDiv("frozenTabs",this.outerDiv);
+ this.innerDiv = this.createDiv("inner",this.outerDiv);
+ this.resizeDiv = this.createDiv("resize",this.outerDiv);
+ this.resizeDiv.style.display="none";
+ this.exportDiv = this.createDiv("export",this.outerDiv);
+ this.exportDiv.style.display="none";
+ //this.frozenTabs.style[this.align[0]]='0px';
+ //this.innerDiv.style[this.align[0]]='0px';
+ Rico.writeDebugMsg("createDivs end");
+ },
+
+ createDiv: function(elemName,elemParent) {
+ var id=this.tableId+"_"+elemName+"Div";
+ newdiv=$(id);
+ if (!newdiv) {
+ var newdiv = document.createElement("div");
+ newdiv.id = id;
+ if (elemParent) elemParent.appendChild(newdiv);
+ }
+ newdiv.className = "ricoLG_"+elemName+"Div";
+ return newdiv;
+ },
+
+ baseSizeDivs: function() {
+ this.setOtherHdrCellWidths();
+ this.tabs[0].style.display=this.options.frozenColumns ? '' : 'none';
+ this.hdrHt=Math.max(RicoUtil.nan2zero(this.thead[0].offsetHeight),this.thead[1].offsetHeight);
+ this.dataHt=Math.max(RicoUtil.nan2zero(this.tbody[0].offsetHeight),this.tbody[1].offsetHeight);
+ this.frzWi=this.borderWidth(this.tabs[0]);
+ var borderWi=this.borderWidth(this.columns[0].dataCell);
+ Rico.writeDebugMsg('baseSizeDivs '+this.tableId+': hdrHt='+this.hdrHt+' dataHt='+this.dataHt);
+ //alert(this.tableId+' frzWi='+this.frzWi+' borderWi='+borderWi);
+ for (var i=0; i<this.options.frozenColumns; i++)
+ if (this.columns[i].visible) this.frzWi+=parseInt(this.columns[i].colWidth)+borderWi;
+ this.scrTabWi=this.borderWidth(this.tabs[1]);
+ for (var i=this.options.frozenColumns; i<this.columns.length; i++)
+ if (this.columns[i].visible) this.scrTabWi+=parseInt(this.columns[i].colWidth)+borderWi;
+ this.scrWi=this.scrTabWi+this.options.scrollBarWidth;
+ var wiLimit=RicoUtil.windowWidth()-this.options.scrollBarWidth-8;
+ if (this.outerDiv.parentNode.clientWidth > 0)
+ wiLimit=Math.min(this.outerDiv.parentNode.clientWidth, wiLimit);
+ var overage=this.frzWi+this.scrWi-wiLimit;
+ Rico.writeDebugMsg('baseSizeDivs '+this.tableId+': scrWi='+this.scrWi+' wiLimit='+wiLimit+' overage='+overage+' clientWidth='+this.outerDiv.parentNode.clientWidth);
+ if (overage > 0 && this.options.frozenColumns < this.columns.length)
+ this.scrWi=Math.max(this.scrWi-overage, this.options.minScrollWidth);
+ this.scrollDiv.style.width=this.scrWi+'px';
+ this.scrollDiv.style.top=this.hdrHt+'px';
+ this.frozenTabs.style.width=this.scrollDiv.style[this.align[0]]=this.innerDiv.style[this.align[0]]=this.frzWi+'px';
+ this.outerDiv.style.width=(this.frzWi+this.scrWi)+'px';
+ },
+
+ borderWidth: function(elem) {
+ return RicoUtil.nan2zero(Element.getStyle(elem,'border-left-width')) + RicoUtil.nan2zero(Element.getStyle(elem,'border-right-width'));
+ },
+
+ setOtherHdrCellWidths: function() {
+ for (var r=0; r<this.hdrCells.length; r++) {
+ if (r==this.headerRowIdx) continue;
+ Rico.writeDebugMsg('setOtherHdrCellWidths: r='+r);
+ var c=i=0;
+ while (i<this.headerColCnt && c<this.hdrCells[r].length) {
+ var hdrcell=this.hdrCells[r][c];
+ var cell=hdrcell.cell;
+ var origSpan=newSpan=hdrcell.colSpan;
+ for (var w=j=0; j<origSpan; j++, i++) {
+ if (this.columns[i].hdrCell.style.display=='none')
+ newSpan--;
+ else if (this.columns[i].hdrColDiv.style.display!='none')
+ w+=parseInt(this.columns[i].colWidth);
+ }
+ if (!hdrcell.hdrColDiv || !hdrcell.hdrCellDiv) {
+ var divs=cell.getElementsByTagName('div');
+ hdrcell.hdrColDiv=(divs.length<1) ? RicoUtil.wrapChildren(cell,'ricoLG_col') : divs[0];
+ hdrcell.hdrCellDiv=(divs.length<2) ? RicoUtil.wrapChildren(hdrcell.hdrColDiv,'ricoLG_cell') : divs[1];
+ }
+ if (newSpan==0) {
+ cell.style.display='none';
+ } else if (w==0) {
+ hdrcell.hdrColDiv.style.display='none';
+ cell.colSpan=newSpan;
+ } else {
+ cell.style.display='';
+ hdrcell.hdrColDiv.style.display='';
+ cell.colSpan=newSpan;
+ hdrcell.hdrColDiv.style.width=w+'px';
+ }
+ c++;
+ }
+ }
+ },
+
+ cell: function(r,c) {
+ return (0<=c && c<this.columns.length && r>=0) ? this.columns[c].cell(r) : null;
+ },
+
+ availHt: function() {
+ var divPos=Position.page(this.outerDiv);
+ return RicoUtil.windowHeight()-divPos[1]-2*this.options.scrollBarWidth-15; // allow for scrollbar and some margin
+ },
+
+ handleScroll: function(e) {
+ var newTop=(this.hdrHt-this.scrollDiv.scrollTop)+'px';
+ this.tabs[0].style.top=newTop;
+ this.setHorizontalScroll();
+ },
+
+ setHorizontalScroll: function() {
+ var newLeft=(-this.scrollDiv.scrollLeft)+'px';
+ this.hdrTabs[1].style.left=newLeft;
+ },
+
+ pluginScroll: function() {
+ if (this.scrollPluggedIn) return;
+ Event.observe(this.scrollDiv,"scroll",this.scrollEventFunc, false);
+ this.scrollPluggedIn=true;
+ },
+
+ unplugScroll: function() {
+ Event.stopObserving(this.scrollDiv,"scroll", this.scrollEventFunc , false);
+ this.scrollPluggedIn=false;
+ },
+
+ printVisible: function(exportType) {
+ this.exportStart();
+ var limit=this.pageSize;
+ if (this.buffer && this.buffer.totalRows < limit) limit=this.buffer.totalRows;
+ for(var r=0; r < limit; r++) {
+ this.exportText+="<tr>";
+ for (var c=0; c<this.columns.length; c++) {
+ if (this.columns[c].visible)
+ this.exportText+="<td style='"+this.exportStyle(this.columns[c].cell(r))+"'>"+this.columns[c].getFormattedValue(r)+"</td>";
+ }
+ this.exportText+="</tr>";
+ }
+ this.exportFinish(exportType);
+ },
+
+ exportStart: function() {
+ this.exportText="<table border='1' cellspacing='0'><thead style='display: table-header-group;'>";
+
+ for (var r=0; r<this.hdrCells.length; r++) {
+ if (this.hdrCells[r].length==0 || Element.getStyle(this.hdrCells[r][0].cell.parentNode,'display')=='none') continue;
+ this.exportText+="<tr>";
+ for (var c=0,i=0; c<this.hdrCells[r].length; c++) {
+ var hdrcell=this.hdrCells[r][c];
+ var newSpan=hdrcell.colSpan;
+ for (var j=0; j<hdrcell.colSpan; j++, i++)
+ if (!this.columns[i].visible) newSpan--;
+ if (newSpan > 0) {
+ var divs=Element.getElementsByClassName(hdrcell.cell,'ricoLG_cell');
+ var cell=divs && divs.length>0 ? divs[0] : hdrcell.cell;
+ this.exportText+="<td style='"+this.exportStyle(cell)+"'";
+ if (hdrcell.colSpan > 1) this.exportText+=" colspan='"+newSpan+"'";
+ this.exportText+=">"+RicoUtil.getInnerText(cell)+"</td>";
+ }
+ }
+ this.exportText+="</tr>";
+ }
+
+ for (var c=0; c<this.columns.length; c++)
+ this.exportText+="</thead><tbody>";
+ },
+
+ exportFinish: function(exportType) {
+ if (this.hideMsg) this.hideMsg();
+ this.exportText+="</tbody></table>";
+ this.exportDiv.innerHTML=this.exportText;
+ this.exportText=undefined;
+ if (this.cancelMenu) this.cancelMenu();
+ window.open(Rico.htmDir+'export-'+(exportType || 'plain')+'.html?'+this.exportDiv.id,'',this.options.exportWindow);
+ },
+
+ exportStyle: function(elem) {
+ var styleList=['background-color','color','text-align','font-weight']
+ for (var i=0,s=''; i < styleList.length; i++) {
+ var curstyle=Element.getStyle(elem,styleList[i]);
+ if (curstyle) s+=styleList[i]+':'+curstyle+';';
+ }
+ return s;
+ },
+
+ // Gets the value of the specified cookie
+ getCookie: function() {
+ var c=RicoUtil.getCookie(this.tableId);
+ if (!c) return;
+ var cookieVals=c.split(',');
+ for (var i=0; i<cookieVals.length; i++) {
+ var v=cookieVals[i].split(':');
+ if (v.length!=2) continue;
+ var colnum=parseInt(v[0].slice(1));
+ if (colnum < 0 || colnum >= this.columns.length) continue;
+ var col=this.columns[colnum];
+ switch (v[0].charAt(0)) {
+ case 'w':
+ col.setColWidth(v[1]);
+ col.customWidth=true;
+ break;
+ case 'h':
+ if (v[1].toLowerCase()=='true')
+ col.showColumn(true);
+ else
+ col.hideColumn(true);
+ break;
+ case 's':
+ col.setSorted(v[1]);
+ break;
+ case 'f':
+ var filterTemp=v[1].split('~');
+ col.filterOp=filterTemp.shift();
+ col.filterValues = [];
+ col.filterType = Rico.TableColumn.USERFILTER;
+ for (var j=0; j<filterTemp.length; j++)
+ col.filterValues.push(unescape(filterTemp[j]));
+ break;
+ }
+ }
+ },
+
+ // Write information to cookie
+ setCookie: function() {
+ var cookieVals=[];
+ for (var i=0; i<this.columns.length; i++) {
+ var col=this.columns[i];
+ if (this.options.saveColumnInfo.width) {
+ if (col.customWidth) cookieVals.push('w'+i+':'+col.colWidth);
+ if (col.customVisible) cookieVals.push('h'+i+':'+col.visible);
+ }
+ if (this.options.saveColumnInfo.sort) {
+ if (col.currentSort != Rico.TableColumn.UNSORTED)
+ cookieVals.push('s'+i+':'+col.currentSort);
+ }
+ if (this.options.saveColumnInfo.filter && col.filterType == Rico.TableColumn.USERFILTER) {
+ var filterTemp=[col.filterOp];
+ for (var j=0; j<col.filterValues.length; j++)
+ filterTemp.push(escape(col.filterValues[j]));
+ cookieVals.push('f'+i+':'+filterTemp.join('~'));
+ }
+ }
+ if (cookieVals.length > 0)
+ RicoUtil.setCookie(this.tableId, cookieVals.join(','), this.options.cookieDays, this.options.cookiePath, this.options.cookieDomain);
+ }
+
+}
+
+Rico.TableColumn = Class.create();
+
+Rico.TableColumn.UNFILTERED = 0;
+Rico.TableColumn.SYSTEMFILTER = 1; /* system-generated filter, not shown to user */
+Rico.TableColumn.USERFILTER = 2;
+
+Rico.TableColumn.UNSORTED = 0;
+Rico.TableColumn.SORT_ASC = "ASC";
+Rico.TableColumn.SORT_DESC = "DESC";
+Rico.TableColumn.MINWIDTH = 10; // min column width when user is resizing
+
+Rico.TableColumn.DOLLAR = {type:'number', prefix:'$', decPlaces:2, ClassName:'alignright'};
+Rico.TableColumn.EURO = {type:'number', prefix:'€', decPlaces:2, ClassName:'alignright'};
+Rico.TableColumn.PERCENT = {type:'number', suffix:'%', decPlaces:2, multiplier:100, ClassName:'alignright'};
+Rico.TableColumn.QTY = {type:'number', decPlaces:0, ClassName:'alignright'};
+Rico.TableColumn.DEFAULT = {type:"raw"};
+
+Rico.TableColumn.prototype = {
+
+ baseInit: function(liveGrid,colIdx,hdrInfo,tabIdx) {
+ Rico.writeDebugMsg("TableColumn.init index="+colIdx+" tabIdx="+tabIdx);
+ this.liveGrid = liveGrid;
+ this.index = colIdx;
+ this.hideWidth = Rico.isKonqueror || Prototype.Browser.WebKit || liveGrid.headerRowCnt>1 ? 5 : 2; // column width used for "hidden" columns. Anything less than 5 causes problems with Konqueror. Best to keep this greater than padding used inside cell.
+ this.options = liveGrid.options;
+ this.tabIdx = tabIdx;
+ this.hdrCell = hdrInfo.cell;
+ this.body = document.getElementsByTagName("body")[0]; // work around FireFox bug (document.body doesn't exist after XSLT)
+ this.displayName = this.getDisplayName(this.hdrCell);
+ var divs=this.hdrCell.getElementsByTagName('div');
+ this.hdrColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.hdrCell,'ricoLG_col') : divs[0];
+ this.hdrCellDiv=(divs.length<2) ? RicoUtil.wrapChildren(this.hdrColDiv,'ricoLG_cell') : divs[1];
+ var sectionIndex= tabIdx==0 ? colIdx : colIdx-liveGrid.options.frozenColumns;
+ this.dataCell = liveGrid.tbody[tabIdx].rows[0].cells[sectionIndex];
+ var divs=this.dataCell.getElementsByTagName('div');
+ this.dataColDiv=(divs.length<1) ? RicoUtil.wrapChildren(this.dataCell,'ricoLG_col') : divs[0];
+
+ this.mouseDownHandler= this.handleMouseDown.bindAsEventListener(this);
+ this.mouseMoveHandler= this.handleMouseMove.bindAsEventListener(this);
+ this.mouseUpHandler = this.handleMouseUp.bindAsEventListener(this);
+ this.mouseOutHandler = this.handleMouseOut.bindAsEventListener(this);
+
+ this.fieldName = 'col'+this.index;
+ var spec = liveGrid.options.columnSpecs[colIdx];
+ this.format=Object.extend( {}, Rico.TableColumn.DEFAULT);
+ switch (typeof spec) {
+ case 'object':
+ if (typeof spec.format=='string') Object.extend(this.format, Rico.TableColumn[spec.format.toUpperCase()]);
+ Object.extend(this.format, spec);
+ break;
+ case 'string':
+ if (spec.slice(0,4)=='spec') spec=spec.slice(4).toUpperCase(); // for backwards compatibility
+ this.format=typeof Rico.TableColumn[spec]=='object' ? Rico.TableColumn[spec] : Rico.TableColumn.DEFAULT;
+ break;
+ }
+ this.dataColDiv.className += (this.format.ClassName) ? ' '+this.format.ClassName : ' '+liveGrid.tableId+'_col'+colIdx;
+ this.visible=true;
+ if (typeof this.format.visible=='boolean') this.visible=this.format.visible;
+ if (typeof this.format.type!='string') this.format.type='raw';
+ Rico.writeDebugMsg("TableColumn.init index="+colIdx+" fieldName="+this.fieldName+' type='+this.format.type);
+ this.sortable = typeof this.format.canSort=='boolean' ? this.format.canSort : liveGrid.options.canSortDefault;
+ this.currentSort = Rico.TableColumn.UNSORTED;
+ this.filterable = typeof this.format.canFilter=='boolean' ? this.format.canFilter : liveGrid.options.canFilterDefault;
+ this.filterType = Rico.TableColumn.UNFILTERED;
+ this.hideable = typeof this.format.canHide=='boolean' ? this.format.canHide : liveGrid.options.canHideDefault;
+ if (typeof this.isNullable!='boolean') this.isNullable = /number|date/.test(this.format.type);
+ this.isText = /raw|text/.test(this.format.type);
+
+ var wi=(typeof(this.format.width)=='number') ? this.format.width : hdrInfo.initWidth;
+ wi=(typeof(wi)=='number') ? Math.max(wi,Rico.TableColumn.MINWIDTH) : liveGrid.options.defaultWidth;
+ this.setColWidth(wi);
+ if (!this.visible) this.setDisplayNone();
+ if (this.options.allowColResize && !this.format.noResize) this.insertResizer();
+ },
+
+ insertResizer: function() {
+ this.hdrCell.style.width='';
+ var resizer=this.hdrCellDiv.appendChild(document.createElement('div'));
+ resizer.className='ricoLG_Resize';
+ resizer.style[this.liveGrid.align[1]]='0px';
+ if (this.options.resizeBackground) {
+ var resizePath=Rico.imgDir+this.options.resizeBackground;
+ if (Prototype.Browser.IE) resizePath=location.protocol+resizePath;
+ resizer.style.backgroundImage='url('+resizePath+')';
+ }
+ Event.observe(resizer,"mousedown", this.mouseDownHandler, false);
+ },
+
+ // get the display name of a column
+ getDisplayName: function(el) {
+ var anchors=el.getElementsByTagName("A");
+ //Check the existance of A tags
+ if (anchors.length > 0)
+ return anchors[0].innerHTML;
+ else
+ return el.innerHTML.stripTags();
+ },
+
+ _clear: function(gridCell) {
+ gridCell.innerHTML=' ';
+ },
+
+ clearCell: function(rowIndex) {
+ var gridCell=this.cell(rowIndex);
+ this._clear(gridCell,rowIndex);
+ if (!this.liveGrid.buffer) return;
+ var acceptAttr=this.liveGrid.buffer.options.acceptAttr;
+ for (var k=0; k<acceptAttr.length; k++) {
+ switch (acceptAttr[k]) {
+ case 'style': gridCell.style.cssText=''; break;
+ case 'class': gridCell.className=''; break;
+ default: gridCell['_'+acceptAttr[k]]=''; break;
+ }
+ }
+ },
+
+ dataTable: function() {
+ return this.liveGrid.tabs[this.tabIdx];
+ },
+
+ numRows: function() {
+ return this.dataColDiv.childNodes.length;
+ },
+
+ clearColumn: function() {
+ var childCnt=this.numRows();
+ for (var r=0; r<childCnt; r++)
+ this.clearCell(r);
+ },
+
+ cell: function(r) {
+ return this.dataColDiv.childNodes[r];
+ },
+
+ getFormattedValue: function(r) {
+ return RicoUtil.getInnerText(this.cell(r));
+ },
+
+ setColWidth: function(wi) {
+ if (typeof wi=='number') {
+ wi=parseInt(wi);
+ if (wi < Rico.TableColumn.MINWIDTH) return;
+ wi=wi+'px';
+ }
+ Rico.writeDebugMsg('setColWidth '+this.index+': '+wi);
+ this.colWidth=wi;
+ this.hdrColDiv.style.width=wi;
+ this.dataColDiv.style.width=wi;
+ },
+
+ pluginMouseEvents: function() {
+ if (this.mousePluggedIn==true) return;
+ Event.observe(this.body,"mousemove", this.mouseMoveHandler, false);
+ Event.observe(this.body,"mouseup", this.mouseUpHandler , false);
+ Event.observe(this.body,"mouseout", this.mouseOutHandler , false);
+ this.mousePluggedIn=true;
+ },
+
+ unplugMouseEvents: function() {
+ Event.stopObserving(this.body,"mousemove", this.mouseMoveHandler, false);
+ Event.stopObserving(this.body,"mouseup", this.mouseUpHandler , false);
+ Event.stopObserving(this.body,"mouseout", this.mouseOutHandler , false);
+ this.mousePluggedIn=false;
+ },
+
+ handleMouseDown: function(e) {
+ this.resizeStart=e.clientX;
+ this.origWidth=parseInt(this.colWidth);
+ var p=Position.positionedOffset(this.hdrCell);
+ if (this.liveGrid.direction=='rtl') {
+ this.edge=p[0]+this.liveGrid.options.scrollBarWidth;
+ switch (this.tabIdx) {
+ case 0: this.edge+=this.liveGrid.innerDiv.offsetWidth; break;
+ case 1: this.edge-=this.liveGrid.scrollDiv.scrollLeft; break;
+ }
+ } else {
+ this.edge=p[0]+this.hdrCell.offsetWidth;
+ if (this.tabIdx>0) this.edge+=RicoUtil.nan2zero(this.liveGrid.tabs[0].offsetWidth)-this.liveGrid.scrollDiv.scrollLeft;
+ }
+ this.liveGrid.resizeDiv.style.left=this.edge+"px";
+ this.liveGrid.resizeDiv.style.display="";
+ this.liveGrid.outerDiv.style.cursor='e-resize';
+ this.tmpHighlight=this.liveGrid.highlightEnabled;
+ this.liveGrid.highlightEnabled=false;
+ this.pluginMouseEvents();
+ Event.stop(e);
+ },
+
+ handleMouseMove: function(e) {
+ var delta=e.clientX-this.resizeStart;
+ var newWidth=(this.liveGrid.direction=='rtl') ? this.origWidth-delta : this.origWidth+delta;
+ if (newWidth < Rico.TableColumn.MINWIDTH) return;
+ this.liveGrid.resizeDiv.style.left=(this.edge+delta)+"px";
+ this.colWidth=newWidth;
+ Event.stop(e);
+ },
+
+ handleMouseUp: function(e) {
+ this.unplugMouseEvents();
+ Rico.writeDebugMsg('handleMouseUp '+this.liveGrid.tableId);
+ this.liveGrid.outerDiv.style.cursor='';
+ this.liveGrid.resizeDiv.style.display="none";
+ this.setColWidth(this.colWidth);
+ this.customWidth=true;
+ this.liveGrid.setCookie();
+ this.liveGrid.highlightEnabled=this.tmpHighlight;
+ this.liveGrid.sizeDivs();
+ Event.stop(e);
+ },
+
+ handleMouseOut: function(e) {
+ var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
+ while (reltg != null && reltg.nodeName.toLowerCase() != 'body')
+ reltg=reltg.parentNode;
+ if (reltg!=null && reltg.nodeName.toLowerCase() == 'body') return true;
+ this.handleMouseUp(e);
+ return true;
+ },
+
+ setDisplayNone: function() {
+ this.hdrCell.style.display='none';
+ this.hdrColDiv.style.display='none';
+ this.dataCell.style.display='none';
+ this.dataColDiv.style.display='none';
+ },
+
+ // recalcTableWidth defaults to true
+ hideColumn: function(noresize) {
+ Rico.writeDebugMsg('hideColumn '+this.liveGrid.tableId);
+ this.setDisplayNone();
+ this.liveGrid.cancelMenu();
+ this.visible=false;
+ this.customVisible=true;
+ if (noresize) return;
+ this.liveGrid.setCookie();
+ this.liveGrid.sizeDivs();
+ },
+
+ showColumn: function(noresize) {
+ Rico.writeDebugMsg('showColumn '+this.liveGrid.tableId);
+ this.hdrCell.style.display='';
+ this.hdrColDiv.style.display='';
+ this.dataCell.style.display='';
+ this.dataColDiv.style.display='';
+ this.liveGrid.cancelMenu();
+ this.visible=true;
+ this.customVisible=true;
+ if (noresize) return;
+ this.liveGrid.setCookie();
+ this.liveGrid.sizeDivs();
+ },
+
+ setImage: function() {
+ if ( this.currentSort == Rico.TableColumn.SORT_ASC ) {
+ this.imgSort.style.display='';
+ this.imgSort.src=Rico.imgDir+this.options.sortAscendImg;
+ } else if ( this.currentSort == Rico.TableColumn.SORT_DESC ) {
+ this.imgSort.style.display='';
+ this.imgSort.src=Rico.imgDir+this.options.sortDescendImg;
+ } else {
+ this.imgSort.style.display='none';
+ }
+ if (this.filterType == Rico.TableColumn.USERFILTER) {
+ this.imgFilter.style.display='';
+ this.imgFilter.title=this.getFilterText();
+ } else {
+ this.imgFilter.style.display='none';
+ }
+ },
+
+ canHideShow: function() {
+ return this.hideable;
+ }
+
+};
+
+Rico.includeLoaded('ricoGridCommon.js');
--- /dev/null
+/**
+ * (c) 2005-2007 Richard Cowin (http://openrico.org)
+ * (c) 2005-2007 Matt Brown (http://dowdybrown.com)
+ *
+ * Rico is 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
+ **/
+
+
+if(typeof Rico=='undefined') throw("LiveGrid requires the Rico JavaScript framework");
+if(typeof RicoUtil=='undefined') throw("LiveGrid requires the RicoUtil Library");
+if(typeof RicoTranslate=='undefined') throw("LiveGrid requires the RicoTranslate Library");
+if(typeof Rico.TableColumn=='undefined') throw("LiveGrid requires ricoGridCommon.js");
+
+
+Rico.Buffer = {};
+
+/**
+ * Loads buffer with data that already exists in the document as an HTML table (no AJAX).
+ * Also serves as a base class for AJAX-enabled buffers.
+ */
+Rico.Buffer.Base = Class.create();
+
+Rico.Buffer.Base.prototype = {
+
+ initialize: function(dataTable, options) {
+ this.clear();
+ this.updateInProgress = false;
+ this.lastOffset = 0;
+ this.rcvdRowCount = false; // true if an eof element was included in the last xml response
+ this.foundRowCount = false; // true if an xml response is ever received with eof true
+ this.totalRows = 0;
+ this.rowcntContent = "";
+ this.rcvdOffset = -1;
+ this.options = {
+ fixedHdrRows : 0,
+ canFilter : false, // does buffer object support filtering?
+ isEncoded : true, // is the data received via ajax html encoded?
+ acceptAttr : [] // attributes that can be copied from original/ajax data (e.g. className, style, id)
+ }
+ Object.extend(this.options, options || {});
+ if (dataTable) {
+ this.loadRowsFromTable(dataTable);
+ } else {
+ this.clear();
+ }
+ },
+
+ registerGrid: function(liveGrid) {
+ this.liveGrid = liveGrid;
+ },
+
+ setTotalRows: function( newTotalRows ) {
+ if (this.totalRows == newTotalRows) return;
+ this.totalRows = newTotalRows;
+ if (this.liveGrid) {
+ Rico.writeDebugMsg("setTotalRows, newTotalRows="+newTotalRows);
+ if (this.liveGrid.sizeTo=='data') this.liveGrid.resizeWindow();
+ this.liveGrid.updateHeightDiv();
+ }
+ },
+
+ loadRowsFromTable: function(tableElement) {
+ this.rows = this.dom2jstable(tableElement,this.options.fixedHdrRows);
+ this.startPos = 0;
+ this.size = this.rows.length;
+ this.setTotalRows(this.size);
+ this.rowcntContent = this.size.toString();
+ this.rcvdRowCount = true;
+ this.foundRowCount = true;
+ },
+
+ dom2jstable: function(rowsElement,firstRow) {
+ var newRows = new Array();
+ var trs = rowsElement.getElementsByTagName("tr");
+ var acceptAttr=this.options.acceptAttr;
+ for ( var i=firstRow || 0; i < trs.length; i++ ) {
+ var row = new Array();
+ var cells = trs[i].getElementsByTagName("td");
+ for ( var j=0; j < cells.length ; j++ ) {
+ row[j]={};
+ row[j].content=RicoUtil.getContentAsString(cells[j],this.options.isEncoded);
+ for (var k=0; k<acceptAttr.length; k++) {
+ row[j]['_'+acceptAttr[k]]=cells[j].getAttribute(acceptAttr[k]);
+ }
+ if (Prototype.Browser.IE) row[j]._class=cells[j].getAttribute('className');
+ }
+ newRows.push( row );
+ }
+ return newRows;
+ },
+
+ _blankRow: function() {
+ var newRow=[];
+ for (var i=0; i<this.liveGrid.columns.length; i++) {
+ newRow[i]={};
+ newRow[i].content='';
+ }
+ return newRow;
+ },
+
+ insertRow: function(beforeRowIndex) {
+ this.rows.splice(beforeRowIndex,0,this._blankRow());
+ },
+
+ appendRows: function(cnt) {
+ for (var i=0; i<cnt; i++)
+ this.rows.push(this._blankRow());
+ this.size=this.rows.length;
+ },
+
+ sortBuffer: function(colnum,sortdir,coltype,getvalfunc) {
+ this.sortColumn=colnum;
+ this.getValFunc=getvalfunc;
+ var sortFunc;
+ switch (coltype) {
+ case 'number': sortFunc=this._sortNumeric.bind(this); break;
+ case 'control':sortFunc=this._sortControl.bind(this); break;
+ default: sortFunc=this._sortAlpha.bind(this); break;
+ }
+ this.rows.sort(sortFunc);
+ if (sortdir=='DESC') this.rows.reverse();
+ },
+
+ _sortAlpha: function(a,b) {
+ var aa = this.sortColumn<a.length ? RicoUtil.getInnerText(a[this.sortColumn].content) : '';
+ var bb = this.sortColumn<b.length ? RicoUtil.getInnerText(b[this.sortColumn].content) : '';
+ if (aa==bb) return 0;
+ if (aa<bb) return -1;
+ return 1;
+ },
+
+ _sortNumeric: function(a,b) {
+ var aa = this.sortColumn<a.length ? parseFloat(RicoUtil.getInnerText(a[this.sortColumn].content)) : 0;
+ if (isNaN(aa)) aa = 0;
+ var bb = this.sortColumn<b.length ? parseFloat(RicoUtil.getInnerText(b[this.sortColumn].content)) : 0;
+ if (isNaN(bb)) bb = 0;
+ return aa-bb;
+ },
+
+ _sortControl: function(a,b) {
+ var aa = this.sortColumn<a.length ? RicoUtil.getInnerText(a[this.sortColumn].content) : '';
+ var bb = this.sortColumn<b.length ? RicoUtil.getInnerText(b[this.sortColumn].content) : '';
+ if (this.getValFunc) {
+ aa=this.getValFunc(aa);
+ bb=this.getValFunc(bb);
+ }
+ if (aa==bb) return 0;
+ if (aa<bb) return -1;
+ return 1;
+ },
+
+ clear: function() {
+ this.rows = new Array();
+ this.startPos = -1;
+ this.size = 0;
+ this.windowPos = 0;
+ },
+
+ isInRange: function(position) {
+ var lastRow=Math.min(this.totalRows, position + this.liveGrid.pageSize)
+ return (position >= this.startPos) && (lastRow <= this.endPos()); // && (this.size != 0);
+ },
+
+ endPos: function() {
+ return this.startPos + this.rows.length;
+ },
+
+ fetch: function(offset) {
+ this.liveGrid.refreshContents(offset);
+ return;
+ },
+
+ exportAllRows: function(populate,finish) {
+ populate(this.getRows(0,this.totalRows));
+ finish();
+ },
+
+ setWindow: function(start, count) {
+ this.windowStart = start - this.startPos;
+ this.windowEnd = Math.min(this.windowStart + count,this.size);
+ this.windowPos = start;
+ },
+
+ isVisible: function(bufRow) {
+ return bufRow < this.rows.length && bufRow >= this.windowStart && bufRow < this.windowEnd;
+ },
+
+ getWindowCell: function(windowRow,col) {
+ var bufrow=this.windowStart+windowRow;
+ return this.isVisible(bufrow) && col < this.rows[bufrow].length ? this.rows[bufrow][col] : null;
+ },
+
+ getWindowValue: function(windowRow,col) {
+ var cell=this.getWindowCell(windowRow,col);
+ return cell ? cell.content : null;
+ },
+
+ setWindowValue: function(windowRow,col,newval) {
+ var bufRow=this.windowStart+windowRow;
+ if (bufRow >= this.windowEnd) return false;
+ return this.setValue(bufRow,col,newval);
+ },
+
+ getCell: function(bufRow,col) {
+ return bufRow < this.size ? this.rows[bufRow][col] : null;
+ },
+
+ getValue: function(bufRow,col) {
+ var cell=this.getCell(bufRow,col);
+ return cell ? cell.content : null;
+ },
+
+ setValue: function(bufRow,col,newval,newstyle) {
+ if (bufRow>=this.size) return false;
+ if (!this.rows[bufRow][col]) this.rows[bufRow][col]={};
+ this.rows[bufRow][col].content=newval;
+ if (typeof newstyle=='string') this.rows[bufRow][col]._style=newstyle;
+ this.rows[bufRow][col].modified=true;
+ return true;
+ },
+
+ getRows: function(start, count) {
+ var begPos = start - this.startPos;
+ var endPos = Math.min(begPos + count,this.size);
+ var results = new Array();
+ for ( var i=begPos; i < endPos; i++ )
+ results.push(this.rows[i]);
+ return results
+ }
+
+};
+
+
+// Rico.LiveGrid -----------------------------------------------------
+
+Rico.LiveGrid = Class.create();
+
+Rico.LiveGrid.prototype = {
+
+ initialize: function( tableId, buffer, options ) {
+ Object.extend(this, new Rico.GridCommon);
+ Object.extend(this, new Rico.LiveGridMethods);
+ this.baseInit();
+ this.tableId = tableId;
+ this.buffer = buffer;
+ Rico.setDebugArea(tableId+"_debugmsgs"); // if used, this should be a textarea
+
+ Object.extend(this.options, {
+ visibleRows : -1, // -1 or 'window'=size grid to client window; -2 or 'data'=size grid to min(window,data); -3 or 'body'=size so body does not have a scrollbar
+ frozenColumns : 0,
+ offset : 0, // first row to be displayed
+ prefetchBuffer : true, // load table on page load?
+ minPageRows : 1,
+ maxPageRows : 50,
+ canSortDefault : true, // can be overridden in the column specs
+ canFilterDefault : buffer.options.canFilter, // can be overridden in the column specs
+ canHideDefault : true, // can be overridden in the column specs
+ cookiePrefix : 'liveGrid.'+tableId,
+
+ // highlight & selection parameters
+ highlightElem : 'none',// what gets highlighted/selected (cursorRow, cursorCell, menuRow, menuCell, selection, or none)
+ highlightSection : 3, // which section gets highlighted (frozen=1, scrolling=2, all=3, none=0)
+ highlightMethod : 'class', // outline, class, both (outline is less CPU intensive on the client)
+ highlightClass : 'ricoLG_selection',
+
+ // export/print parameters
+ maxPrint : 1000, // max # of rows that can be printed/exported, 0=disable print/export feature
+ exportWindow : "height=300,width=500,scrollbars=1,menubar=1,resizable=1",
+
+ // heading parameters
+ headingSort : 'link', // link: make headings a link that will sort column, hover: make headings a hoverset, none: events on headings are disabled
+ hdrIconsFirst : true, // true: put sort & filter icons before header text, false: after
+ sortAscendImg : 'sort_asc.gif',
+ sortDescendImg : 'sort_desc.gif',
+ filterImg : 'filtercol.gif'
+ });
+ // other options:
+ // sortCol: initial sort column
+
+ this.options.sortHandler = this.sortHandler.bind(this);
+ this.options.filterHandler = this.filterHandler.bind(this);
+ this.options.onRefreshComplete = this.bookmarkHandler.bind(this);
+ this.options.rowOverHandler = this.rowMouseOver.bindAsEventListener(this);
+ this.options.mouseDownHandler = this.selectMouseDown.bindAsEventListener(this);
+ this.options.mouseOverHandler = this.selectMouseOver.bindAsEventListener(this);
+ this.options.mouseUpHandler = this.selectMouseUp.bindAsEventListener(this);
+ Object.extend(this.options, options || {});
+
+ switch (typeof this.options.visibleRows) {
+ case 'string':
+ this.sizeTo=this.options.visibleRows;
+ this.options.visibleRows=-1;
+ break;
+ case 'number':
+ switch (this.options.visibleRows) {
+ case -1: this.sizeTo='window'; break;
+ case -2: this.sizeTo='data'; break;
+ case -3: this.sizeTo='body'; break;
+ }
+ break;
+ default:
+ this.sizeTo='window';
+ this.options.visibleRows=-1;
+ }
+ this.highlightEnabled=this.options.highlightSection>0;
+ this.pageSize=0;
+ this.createTables();
+ if (this.headerColCnt==0) {
+ alert('ERROR: no columns found in "'+this.tableId+'"');
+ return;
+ }
+ this.createColumnArray();
+ if (this.options.headingSort=='hover')
+ this.createHoverSet();
+
+ this.bookmark=$(this.tableId+"_bookmark");
+ this.sizeDivs();
+ this.createDataCells(this.options.visibleRows);
+ if (this.pageSize == 0) return;
+ this.buffer.registerGrid(this);
+ if (this.buffer.setBufferSize) this.buffer.setBufferSize(this.pageSize);
+ this.scrollTimeout = null;
+ this.lastScrollPos = 0;
+ this.attachMenuEvents();
+
+ // preload the images...
+ new Image().src = Rico.imgDir+this.options.filterImg;
+ new Image().src = Rico.imgDir+this.options.sortAscendImg;
+ new Image().src = Rico.imgDir+this.options.sortDescendImg;
+ Rico.writeDebugMsg("images preloaded");
+
+ this.setSortUI( this.options.sortCol, this.options.sortDir );
+ this.setImages();
+ if (this.listInvisible().length==this.columns.length)
+ this.columns[0].showColumn();
+ this.sizeDivs();
+ this.scrollDiv.style.display="";
+ if (this.buffer.totalRows>0)
+ this.updateHeightDiv();
+ if (this.options.prefetchBuffer) {
+ if (this.bookmark) this.bookmark.innerHTML = RicoTranslate.getPhrase("Loading...");
+ if (this.options.canFilterDefault && this.options.getQueryParms)
+ this.checkForFilterParms();
+ this.buffer.fetch(this.options.offset);
+ }
+ this.scrollEventFunc=this.handleScroll.bindAsEventListener(this);
+ this.wheelEventFunc=this.handleWheel.bindAsEventListener(this);
+ this.wheelEvent=(Prototype.Browser.IE || Prototype.Browser.Opera || Prototype.Browser.WebKit) ? 'mousewheel' : 'DOMMouseScroll';
+ if (this.options.offset && this.options.offset < this.buffer.totalRows)
+ setTimeout(this.scrollToRow.bind(this,this.options.offset),50); // Safari requires a delay
+ this.pluginScroll();
+ this.setHorizontalScroll();
+ if (this.options.windowResize)
+ setTimeout(this.pluginWindowResize.bind(this),100);
+ }
+};
+
+Rico.LiveGridMethods = function() {};
+
+Rico.LiveGridMethods.prototype = {
+
+ createHoverSet: function() {
+ var hdrs=[];
+ for( var c=0; c < this.headerColCnt; c++ )
+ hdrs.push(this.columns[c].hdrCellDiv);
+ this.hoverSet = new Rico.HoverSet(hdrs);
+ },
+
+ checkForFilterParms: function() {
+ var s=window.location.search;
+ if (s.charAt(0)=='?') s=s.substring(1);
+ var pairs = s.split('&');
+ for (var i=0; i<pairs.length; i++)
+ if (pairs[i].match(/^f\[\d+\]/)) {
+ this.buffer.options.requestParameters.push(pairs[i]);
+ }
+ },
+
+/**
+ * Create one table for frozen columns and one for scrolling columns.
+ * Also create div's to contain them.
+ */
+ createTables: function() {
+ var insertloc;
+ var result = -1;
+ var table = $(this.tableId);
+ if (!table) return result;
+ if (table.tagName.toLowerCase()=='table') {
+ var theads=table.getElementsByTagName("thead");
+ if (theads.length == 1) {
+ Rico.writeDebugMsg("createTables: using thead section, id="+this.tableId);
+ var hdrSrc=theads[0].rows;
+ } else {
+ Rico.writeDebugMsg("createTables: using tbody section, id="+this.tableId);
+ var hdrSrc=new Array(table.rows[0]);
+ }
+ insertloc=table;
+ } else if (this.options.columnSpecs.length > 0) {
+ insertloc=table;
+ Rico.writeDebugMsg("createTables: inserting at "+table.tagName+", id="+this.tableId);
+ } else {
+ alert("ERROR!\n\nUnable to initialize '"+this.tableId+"'\n\nLiveGrid terminated");
+ return result;
+ }
+
+ this.createDivs();
+ this.scrollTabs = this.createDiv("scrollTabs",this.innerDiv);
+ this.shadowDiv = this.createDiv("shadow",this.scrollDiv);
+ this.shadowDiv.style.direction='ltr'; // avoid FF bug
+ this.messageDiv = this.createDiv("message",this.outerDiv);
+ this.messageDiv.style.display="none";
+ this.messageShadow=new Rico.Shadow(this.messageDiv);
+ this.scrollDiv.style.display="none";
+ this.scrollDiv.scrollTop=0;
+ if (this.options.highlightMethod!='class') {
+ this.highlightDiv=[];
+ switch (this.options.highlightElem) {
+ case 'menuRow':
+ case 'cursorRow':
+ this.highlightDiv[0] = this.createDiv("highlight",this.outerDiv);
+ this.highlightDiv[0].style.display="none";
+ break;
+ case 'menuCell':
+ case 'cursorCell':
+ for (var i=0; i<2; i++) {
+ this.highlightDiv[i] = this.createDiv("highlight",i==0 ? this.frozenTabs : this.scrollTabs);
+ this.highlightDiv[i].style.display="none";
+ this.highlightDiv[i].id+=i;
+ }
+ break;
+ case 'selection':
+ // create one div for each side of the rectangle
+ var parentDiv=this.options.highlightSection==1 ? this.frozenTabs : this.scrollTabs;
+ for (var i=0; i<4; i++) {
+ this.highlightDiv[i] = this.createDiv("highlight",parentDiv);
+ this.highlightDiv[i].style.display="none";
+ this.highlightDiv[i].id+=i;
+ this.highlightDiv[i].style[i % 2==0 ? 'height' : 'width']="0px";
+ }
+ break;
+ }
+ }
+
+ // create new tables
+ for (var i=0; i<2; i++) {
+ this.tabs[i] = document.createElement("table");
+ this.tabs[i].className = 'ricoLG_table';
+ this.tabs[i].border=0;
+ this.tabs[i].cellPadding=0;
+ this.tabs[i].cellSpacing=0;
+ this.tabs[i].id = this.tableId+"_tab"+i;
+ this.thead[i]=this.tabs[i].createTHead();
+ this.thead[i].className='ricoLG_top';
+ if (this.tabs[i].tBodies.length==0)
+ this.tbody[i]=this.tabs[i].appendChild(document.createElement("tbody"));
+ else
+ this.tbody[i]=this.tabs[i].tBodies[0];
+ this.tbody[i].className='ricoLG_bottom';
+ this.tbody[i].insertRow(-1);
+ }
+ this.frozenTabs.appendChild(this.tabs[0]);
+ this.scrollTabs.appendChild(this.tabs[1]);
+ insertloc.parentNode.insertBefore(this.outerDiv,insertloc);
+ if (hdrSrc)
+ this.loadHdrSrc(hdrSrc);
+ else
+ this.createHdr();
+ for( var c=0; c < this.headerColCnt; c++ )
+ this.tbody[c<this.options.frozenColumns ? 0 : 1].rows[0].insertCell(-1);
+ if (table) table.parentNode.removeChild(table);
+ Rico.writeDebugMsg('createTables end');
+ },
+
+ createDataCells: function(visibleRows) {
+ if (visibleRows < 0) {
+ this.appendBlankRow();
+ this.sizeDivs();
+ this.autoAppendRows(this.remainingHt());
+ } else {
+ for( var r=0; r < visibleRows; r++ )
+ this.appendBlankRow();
+ }
+ var s=this.options.highlightSection;
+ if (s & 1) this.attachHighlightEvents(this.tbody[0]);
+ if (s & 2) this.attachHighlightEvents(this.tbody[1]);
+ return;
+ },
+
+ createHdr: function() {
+ for (var i=0; i<2; i++) {
+ var start=(i==0) ? 0 : this.options.frozenColumns;
+ var limit=(i==0) ? this.options.frozenColumns : this.options.columnSpecs.length;
+ Rico.writeDebugMsg('createHdr: i='+i+' start='+start+' limit='+limit);
+ if (this.options.PanelNamesOnTabHdr && this.options.panels) {
+ // place panel names on first row of thead
+ var r = this.thead[i].insertRow(-1);
+ r.className='ricoLG_hdg';
+ var lastIdx=-1, span, newCell=null, spanIdx=0;
+ for( var c=start; c < limit; c++ ) {
+ if (lastIdx == this.options.columnSpecs[c].panelIdx) {
+ span++;
+ } else {
+ if (newCell) newCell.colSpan=span;
+ newCell = r.insertCell(-1);
+ span=1;
+ lastIdx=this.options.columnSpecs[c].panelIdx;
+ newCell.innerHTML=this.options.panels[lastIdx];
+ }
+ }
+ if (newCell) newCell.colSpan=span;
+ }
+ var mainRow = this.thead[i].insertRow(-1);
+ mainRow.id=this.tableId+'_tab'+i+'h_main';
+ mainRow.className='ricoLG_hdg';
+ for( var c=start; c < limit; c++ ) {
+ var newCell = mainRow.insertCell(-1);
+ newCell.innerHTML=this.options.columnSpecs[c].Hdg;
+ }
+ this.headerColCnt = this.getColumnInfo(this.thead[i].rows);
+ }
+ },
+
+ loadHdrSrc: function(hdrSrc) {
+ Rico.writeDebugMsg('loadHdrSrc start');
+ this.headerColCnt = this.getColumnInfo(hdrSrc);
+ for (var i=0; i<2; i++) {
+ for (var r=0; r<hdrSrc.length; r++) {
+ var newrow = this.thead[i].insertRow(-1);
+ newrow.className='ricoLG_hdg';
+ }
+ }
+ if (hdrSrc.length==1) {
+ var cells=hdrSrc[0].cells;
+ for (var c=0; cells.length > 0; c++)
+ this.thead[c<this.options.frozenColumns ? 0 : 1].rows[0].appendChild(cells[0]);
+ } else {
+ for (var r=0; r<hdrSrc.length; r++) {
+ var cells=hdrSrc[r].cells;
+ for (var c=0; cells.length > 0; c++) {
+ if (cells[0].className=='ricoFrozen') {
+ this.thead[0].rows[r].appendChild(cells[0]);
+ if (r==this.headerRowIdx) this.options.frozenColumns=c+1;
+ } else {
+ this.thead[1].rows[r].appendChild(cells[0]);
+ }
+ }
+ }
+ }
+ Rico.writeDebugMsg('loadHdrSrc end');
+ },
+
+ sizeDivs: function() {
+ Rico.writeDebugMsg('sizeDivs: '+this.tableId);
+ this.cancelMenu();
+ this.unhighlight();
+ this.baseSizeDivs();
+ if (this.pageSize == 0) return;
+ this.rowHeight = Math.round(this.dataHt/this.pageSize);
+ var scrHt=this.dataHt;
+ if (this.scrWi>0 || Prototype.Browser.IE || Prototype.Browser.WebKit)
+ scrHt+=this.options.scrollBarWidth;
+ this.scrollDiv.style.height=scrHt+'px';
+ this.innerDiv.style.width=(this.scrWi-this.options.scrollBarWidth+1)+'px';
+ this.resizeDiv.style.height=this.frozenTabs.style.height=this.innerDiv.style.height=(this.hdrHt+this.dataHt+1)+'px';
+ Rico.writeDebugMsg('sizeDivs scrHt='+scrHt+' innerHt='+this.innerDiv.style.height+' rowHt='+this.rowHeight+' pageSize='+this.pageSize);
+ pad=(this.scrWi-this.scrTabWi < this.options.scrollBarWidth) ? 2 : 0;
+ this.shadowDiv.style.width=(this.scrTabWi+pad)+'px';
+ this.outerDiv.style.height=(this.hdrHt+scrHt)+'px';
+ this.setHorizontalScroll();
+ },
+
+ setHorizontalScroll: function() {
+ var scrleft=this.scrollDiv.scrollLeft;
+ this.scrollTabs.style.left=(-scrleft)+'px';
+ },
+
+ remainingHt: function() {
+ var winHt=RicoUtil.windowHeight();
+ var margin=Prototype.Browser.IE ? 15 : 10;
+ switch (this.sizeTo) {
+ case 'window':
+ case 'data':
+ var divPos=Position.page(this.outerDiv);
+ var tabHt=Math.max(this.tabs[0].offsetHeight,this.tabs[1].offsetHeight);
+ Rico.writeDebugMsg("remainingHt, winHt="+winHt+' tabHt='+tabHt+' gridY='+divPos[1]);
+ return winHt-divPos[1]-tabHt-this.options.scrollBarWidth-margin; // allow for scrollbar and some margin
+ case 'body':
+ //Rico.writeDebugMsg("remainingHt, document.height="+document.height);
+ //Rico.writeDebugMsg("remainingHt, body.offsetHeight="+document.body.offsetHeight);
+ //Rico.writeDebugMsg("remainingHt, body.scrollHeight="+document.body.scrollHeight);
+ //Rico.writeDebugMsg("remainingHt, documentElement.scrollHeight="+document.documentElement.scrollHeight);
+ var bodyHt=Prototype.Browser.IE ? document.body.scrollHeight : document.body.offsetHeight;
+ var remHt=winHt-bodyHt-margin;
+ if (!Prototype.Browser.WebKit) remHt-=this.options.scrollBarWidth;
+ Rico.writeDebugMsg("remainingHt, winHt="+winHt+' pageHt='+bodyHt+' remHt='+remHt);
+ return remHt;
+ }
+ },
+
+ adjustPageSize: function() {
+ var remHt=this.remainingHt();
+ Rico.writeDebugMsg('adjustPageSize remHt='+remHt+' lastRow='+this.lastRowPos);
+ if (remHt > this.rowHeight)
+ this.autoAppendRows(remHt);
+ else if (remHt < 0 || this.sizeTo=='data')
+ this.autoRemoveRows(-remHt);
+ },
+
+ pluginWindowResize: function() {
+ Event.observe(window, "resize", this.resizeWindow.bindAsEventListener(this), false);
+ },
+
+ resizeWindow: function() {
+ Rico.writeDebugMsg('resizeWindow '+this.tableId+' lastRow='+this.lastRowPos);
+ if (!this.sizeTo) {
+ this.sizeDivs();
+ return;
+ }
+ var oldSize=this.pageSize;
+ this.adjustPageSize();
+ if (this.pageSize > oldSize) {
+ this.isPartialBlank=true;
+ var adjStart=this.adjustRow(this.lastRowPos);
+ this.buffer.fetch(adjStart);
+ }
+ if (oldSize != this.pageSize)
+ setTimeout(this.finishResize.bind(this),50);
+ else
+ this.sizeDivs();
+ Rico.writeDebugMsg('resizeWindow complete. old size='+oldSize+' new size='+this.pageSize);
+ },
+
+ finishResize: function() {
+ this.sizeDivs();
+ this.updateHeightDiv();
+ },
+
+ topOfLastPage: function() {
+ return Math.max(this.buffer.totalRows-this.pageSize,0);
+ },
+
+ updateHeightDiv: function() {
+ var notdisp=this.topOfLastPage();
+ var ht = this.scrollDiv.clientHeight + this.rowHeight * notdisp;
+ //if (Prototype.Browser.Opera) ht+=this.options.scrollBarWidth-3;
+ Rico.writeDebugMsg("updateHeightDiv, ht="+ht+' scrollDiv.clientHeight='+this.scrollDiv.clientHeight+' rowsNotDisplayed='+notdisp);
+ this.shadowDiv.style.height=ht+'px';
+ },
+
+ autoRemoveRows: function(overage) {
+ var removeCnt=Math.ceil(overage / this.rowHeight);
+ if (this.sizeTo=='data')
+ removeCnt=Math.max(removeCnt,this.pageSize-this.buffer.totalRows);
+ Rico.writeDebugMsg("autoRemoveRows overage="+overage+" removeCnt="+removeCnt);
+ for (var i=0; i<removeCnt; i++)
+ this.removeRow();
+ },
+
+ removeRow: function() {
+ if (this.pageSize <= this.options.minPageRows) return;
+ this.pageSize--;
+ for( var c=0; c < this.headerColCnt; c++ ) {
+ var cell=this.columns[c].cell(this.pageSize);
+ this.columns[c].dataColDiv.removeChild(cell);
+ }
+ },
+
+ autoAppendRows: function(overage) {
+ var addCnt=Math.floor(overage / this.rowHeight);
+ Rico.writeDebugMsg("autoAppendRows overage="+overage+" cnt="+addCnt+" rowHt="+this.rowHeight);
+ for (var i=0; i<addCnt; i++) {
+ if (this.sizeTo=='data' && this.pageSize>=this.buffer.totalRows) break;
+ this.appendBlankRow();
+ }
+ },
+
+ // on older systems, this can be fairly slow
+ appendBlankRow: function() {
+ if (this.pageSize >= this.options.maxPageRows) return;
+ Rico.writeDebugMsg("appendBlankRow #"+this.pageSize);
+ var cls=this.defaultRowClass(this.pageSize);
+ for( var c=0; c < this.headerColCnt; c++ ) {
+ var newdiv = document.createElement("div");
+ newdiv.className = 'ricoLG_cell '+cls;
+ newdiv.id=this.tableId+'_'+this.pageSize+'_'+c;
+ this.columns[c].dataColDiv.appendChild(newdiv);
+ newdiv.innerHTML=' ';
+ if (this.columns[c]._create)
+ this.columns[c]._create(newdiv,this.pageSize);
+ }
+ this.pageSize++;
+ },
+
+ defaultRowClass: function(rownum) {
+ return (rownum % 2==0) ? 'ricoLG_evenRow' : 'ricoLG_oddRow';
+ },
+
+ handleMenuClick: function(e) {
+ //Event.stop(e);
+ if (!this.menu) return;
+ this.cancelMenu();
+ this.unhighlight(); // in case highlighting was invoked externally
+ var cell=Event.element(e);
+ if (cell.className=='ricoLG_highlightDiv') {
+ var idx=this.highlightIdx;
+ } else {
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ var idx=this.winCellIndex(cell);
+ if ((this.options.highlightSection & (idx.tabIdx+1))==0) return;
+ }
+ this.highlight(idx);
+ this.highlightEnabled=false;
+ if (this.hideScroll) this.scrollDiv.style.overflow="hidden";
+ this.menuIdx=idx;
+ if (!this.menu.div) this.menu.createDiv();
+ this.menu.liveGrid=this;
+ if (this.menu.buildGridMenu) {
+ var showMenu=this.menu.buildGridMenu(idx.row, idx.column, idx.tabIdx);
+ if (!showMenu) return;
+ }
+ if (this.options.highlightElem=='selection' && !this.isSelected(idx.cell))
+ this.selectCell(idx.cell);
+ this.menu.showmenu(e,this.closeMenu.bind(this));
+ },
+
+ closeMenu: function() {
+ if (!this.menuIdx) return;
+ if (this.hideScroll) this.scrollDiv.style.overflow="";
+ this.unhighlight();
+ this.highlightEnabled=true;
+ this.menuIdx=null;
+ },
+
+/**
+ * @return index of cell within the window
+ */
+ winCellIndex: function(cell) {
+ var a=cell.id.split(/_/);
+ var l=a.length;
+ var r=parseInt(a[l-2]);
+ var c=parseInt(a[l-1]);
+ return {row:r, column:c, tabIdx:this.columns[c].tabIdx, cell:cell};
+ },
+
+/**
+ * @return index of cell within the buffer
+ */
+ bufCellIndex: function(cell) {
+ var idx=this.winCellIndex(cell);
+ idx.row+=this.buffer.windowPos;
+ if (idx.row >= this.buffer.size) idx.onBlankRow=true;
+ return idx;
+ },
+
+ attachHighlightEvents: function(tBody) {
+ switch (this.options.highlightElem) {
+ case 'selection':
+ Event.observe(tBody,"mousedown", this.options.mouseDownHandler, false);
+ tBody.ondrag = function () { return false; };
+ tBody.onselectstart = function () { return false; };
+ break;
+ case 'cursorRow':
+ case 'cursorCell':
+ Event.observe(tBody,"mouseover", this.options.rowOverHandler, false);
+ break;
+ }
+ },
+
+ getVisibleSelection: function() {
+ var cellList=[];
+ if (this.SelectIdxStart && this.SelectIdxEnd) {
+ var r1=Math.max(Math.min(this.SelectIdxEnd.row,this.SelectIdxStart.row),this.buffer.windowPos);
+ var r2=Math.min(Math.max(this.SelectIdxEnd.row,this.SelectIdxStart.row),this.buffer.windowEnd-1);
+ var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ for (var r=r1; r<=r2; r++)
+ for (var c=c1; c<=c2; c++)
+ cellList.push({row:r-this.buffer.windowPos,column:c});
+ }
+ if (this.SelectCtrl) {
+ for (var i=0; i<this.SelectCtrl.length; i++) {
+ if (this.SelectCtrl[i].row>=this.buffer.windowPos && this.SelectCtrl[i].row<this.buffer.windowEnd)
+ cellList.push({row:this.SelectCtrl[i].row-this.buffer.windowPos,column:this.SelectCtrl[i].column});
+ }
+ }
+ return cellList;
+ },
+
+ updateSelectOutline: function() {
+ if (!this.SelectIdxStart || !this.SelectIdxEnd) return;
+ var r1=Math.max(Math.min(this.SelectIdxEnd.row,this.SelectIdxStart.row), this.buffer.windowStart);
+ var r2=Math.min(Math.max(this.SelectIdxEnd.row,this.SelectIdxStart.row), this.buffer.windowEnd-1);
+ if (r1 > r2) {
+ this.HideSelection();
+ return;
+ }
+ var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ var top1=this.columns[c1].cell(r1-this.buffer.windowStart).offsetTop;
+ var cell2=this.columns[c1].cell(r2-this.buffer.windowStart);
+ var bottom2=cell2.offsetTop+cell2.offsetHeight;
+ var left1=this.columns[c1].dataCell.offsetLeft;
+ var left2=this.columns[c2].dataCell.offsetLeft;
+ var right2=left2+this.columns[c2].dataCell.offsetWidth;
+ //window.status='updateSelectOutline: '+r1+' '+r2+' top='+top1+' bot='+bottom2;
+ this.highlightDiv[0].style.top=this.highlightDiv[3].style.top=this.highlightDiv[1].style.top=(this.hdrHt+top1-1) + 'px';
+ this.highlightDiv[2].style.top=(this.hdrHt+bottom2-1)+'px';
+ this.highlightDiv[3].style.left=(left1-2)+'px';
+ this.highlightDiv[0].style.left=this.highlightDiv[2].style.left=(left1-1)+'px';
+ this.highlightDiv[1].style.left=(right2-1)+'px';
+ this.highlightDiv[0].style.width=this.highlightDiv[2].style.width=(right2-left1-1) + 'px';
+ this.highlightDiv[1].style.height=this.highlightDiv[3].style.height=(bottom2-top1) + 'px';
+ //this.highlightDiv[0].style.right=this.highlightDiv[2].style.right=this.highlightDiv[1].style.right=()+'px';
+ //this.highlightDiv[2].style.bottom=this.highlightDiv[3].style.bottom=this.highlightDiv[1].style.bottom=(this.hdrHt+bottom2) + 'px';
+ for (var i=0; i<4; i++)
+ this.highlightDiv[i].style.display='';
+ },
+
+ HideSelection: function(cellList) {
+ if (this.options.highlightMethod!='class') {
+ for (var i=0; i<4; i++)
+ this.highlightDiv[i].style.display='none';
+ }
+ if (this.options.highlightMethod!='outline') {
+ var cellList=this.getVisibleSelection();
+ for (var i=0; i<cellList.length; i++)
+ this.unhighlightCell(this.columns[cellList[i].column].cell(cellList[i].row));
+ }
+ },
+
+ ShowSelection: function() {
+ if (this.options.highlightMethod!='class')
+ this.updateSelectOutline();
+ if (this.options.highlightMethod!='outline') {
+ var cellList=this.getVisibleSelection();
+ for (var i=0; i<cellList.length; i++)
+ this.highlightCell(this.columns[cellList[i].column].cell(cellList[i].row));
+ }
+ },
+
+ ClearSelection: function() {
+ this.HideSelection();
+ this.SelectIdxStart=null;
+ this.SelectIdxEnd=null;
+ this.SelectCtrl=[];
+ },
+
+ selectCell: function(cell) {
+ this.ClearSelection();
+ this.SelectIdxStart=this.SelectIdxEnd=this.bufCellIndex(cell);
+ this.ShowSelection();
+ },
+
+ AdjustSelection: function(cell) {
+ var newIdx=this.bufCellIndex(cell);
+ if (this.SelectIdxStart.tabIdx != newIdx.tabIdx) return;
+ this.HideSelection();
+ this.SelectIdxEnd=newIdx;
+ this.ShowSelection();
+ },
+
+ RefreshSelection: function() {
+ var cellList=this.getVisibleSelection();
+ for (var i=0; i<cellList.length; i++)
+ this.columns[cellList[i].column].displayValue(cellList[i].row);
+ },
+
+ FillSelection: function(newVal,newStyle) {
+ if (this.SelectIdxStart && this.SelectIdxEnd) {
+ var r1=Math.min(this.SelectIdxEnd.row,this.SelectIdxStart.row);
+ var r2=Math.max(this.SelectIdxEnd.row,this.SelectIdxStart.row);
+ var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ for (var r=r1; r<=r2; r++)
+ for (var c=c1; c<=c2; c++)
+ this.buffer.setValue(r,c,newVal,newStyle);
+ }
+ if (this.SelectCtrl) {
+ for (var i=0; i<this.SelectCtrl.length; i++)
+ this.buffer.setValue(this.SelectCtrl[i].row,this.SelectCtrl[i].column,newVal,newStyle);
+ }
+ this.RefreshSelection();
+ },
+
+ selectMouseDown: function(e) {
+ if (this.highlightEnabled==false) return true;
+ this.cancelMenu();
+ var cell=Event.element(e);
+ Event.stop(e);
+ if (!Event.isLeftClick(e)) return;
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ var newIdx=this.bufCellIndex(cell);
+ if (newIdx.onBlankRow) return;
+ if (e.ctrlKey) {
+ if (!this.SelectIdxStart || this.options.highlightMethod!='class') return;
+ if (!this.isSelected(cell)) {
+ this.highlightCell(cell);
+ this.SelectCtrl.push(this.bufCellIndex(cell));
+ } else {
+ for (var i=0; i<this.SelectCtrl.length; i++) {
+ if (this.SelectCtrl[i].row==newIdx.row && this.SelectCtrl[i].column==newIdx.column) {
+ this.unhighlightCell(cell);
+ this.SelectCtrl.splice(i,1);
+ break;
+ }
+ }
+ }
+ } else if (e.shiftKey) {
+ if (!this.SelectIdxStart) return;
+ this.AdjustSelection(cell);
+ } else {
+ this.selectCell(cell);
+ this.pluginSelect();
+ }
+ },
+
+ pluginSelect: function() {
+ if (this.selectPluggedIn) return;
+ var tBody=this.tbody[this.SelectIdxStart.tabIdx];
+ Event.observe(tBody,"mouseover", this.options.mouseOverHandler, false);
+ Event.observe(this.outerDiv,"mouseup", this.options.mouseUpHandler, false);
+ if (this.options.highlightMethod!='class')
+ this.selectPluggedIn=true;
+ },
+
+ unplugSelect: function() {
+ var tBody=this.tbody[this.SelectIdxStart.tabIdx];
+ Event.stopObserving(tBody,"mouseover", this.options.mouseOverHandler , false);
+ Event.stopObserving(this.outerDiv,"mouseup", this.options.mouseUpHandler , false);
+ this.selectPluggedIn=false;
+ },
+
+ selectMouseUp: function(e) {
+ this.unplugSelect();
+ var cell=Event.element(e);
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ if (this.SelectIdxStart && this.SelectIdxEnd)
+ this.AdjustSelection(cell);
+ else
+ this.ClearSelection();
+ },
+
+ selectMouseOver: function(e) {
+ var cell=Event.element(e);
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ this.AdjustSelection(cell);
+ Event.stop(e);
+ },
+
+ isSelected: function(cell) {
+ return Element.hasClassName(cell,this.options.highlightClass);
+ },
+
+ highlightCell: function(cell) {
+ Element.addClassName(cell,this.options.highlightClass);
+ },
+
+ unhighlightCell: function(cell) {
+ if (cell==null) return;
+ Element.removeClassName(cell,this.options.highlightClass);
+ },
+
+ selectRow: function(r) {
+ for (var c=0; c<this.columns.length; c++)
+ this.highlightCell(this.columns[c].cell(r));
+ },
+
+ unselectRow: function(r) {
+ for (var c=0; c<this.columns.length; c++)
+ this.unhighlightCell(this.columns[c].cell(r));
+ },
+
+ rowMouseOver: function(e) {
+ if (!this.highlightEnabled) return;
+ var cell=Event.element(e);
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ var newIdx=this.winCellIndex(cell);
+ if ((this.options.highlightSection & (newIdx.tabIdx+1))==0) return;
+ this.highlight(newIdx);
+ },
+
+ highlight: function(newIdx) {
+ if (this.options.highlightMethod!='outline') this.cursorSetClass(newIdx);
+ if (this.options.highlightMethod!='class') this.cursorOutline(newIdx);
+ this.highlightIdx=newIdx;
+ },
+
+ cursorSetClass: function(newIdx) {
+ switch (this.options.highlightElem) {
+ case 'menuCell':
+ case 'cursorCell':
+ if (this.highlightIdx) this.unhighlightCell(this.highlightIdx.cell);
+ this.highlightCell(newIdx.cell);
+ break;
+ case 'menuRow':
+ case 'cursorRow':
+ if (this.highlightIdx) this.unselectRow(this.highlightIdx.row);
+ var s1=this.options.highlightSection & 1;
+ var s2=this.options.highlightSection & 2;
+ var c0=s1 ? 0 : this.options.frozenColumns;
+ var c1=s2 ? this.columns.length : this.options.frozenColumns;
+ for (var c=c0; c<c1; c++)
+ this.highlightCell(this.columns[c].cell(newIdx.row));
+ break;
+ default: return;
+ }
+ },
+
+ cursorOutline: function(newIdx) {
+ switch (this.options.highlightElem) {
+ case 'menuCell':
+ case 'cursorCell':
+ var div=this.highlightDiv[newIdx.tabIdx];
+ div.style.left=(this.columns[newIdx.column].dataCell.offsetLeft-1)+'px';
+ div.style.width=this.columns[newIdx.column].colWidth;
+ this.highlightDiv[1-newIdx.tabIdx].style.display='none';
+ break;
+ case 'menuRow':
+ case 'cursorRow':
+ var div=this.highlightDiv[0];
+ var s1=this.options.highlightSection & 1;
+ var s2=this.options.highlightSection & 2;
+ div.style.left=s1 ? '0px' : this.frozenTabs.style.width;
+ div.style.width=((s1 ? this.frozenTabs.offsetWidth : 0) + (s2 ? this.innerDiv.offsetWidth : 0) - 4)+'px';
+ break;
+ default: return;
+ }
+ div.style.top=(this.hdrHt+newIdx.row*this.rowHeight-1)+'px';
+ div.style.height=(this.rowHeight-1)+'px';
+ div.style.display='';
+ },
+
+ unhighlight: function() {
+ switch (this.options.highlightElem) {
+ case 'menuCell':
+ this.highlightIdx=this.menuIdx;
+ case 'cursorCell':
+ if (this.highlightIdx) this.unhighlightCell(this.highlightIdx.cell);
+ if (!this.highlightDiv) return;
+ for (var i=0; i<2; i++)
+ this.highlightDiv[i].style.display='none';
+ break;
+ case 'menuRow':
+ this.highlightIdx=this.menuIdx;
+ case 'cursorRow':
+ if (this.highlightIdx) this.unselectRow(this.highlightIdx.row);
+ if (this.highlightDiv) this.highlightDiv[0].style.display='none';
+ break;
+ }
+ },
+
+ hideMsg: function() {
+ if (this.messageDiv.style.display=="none") return;
+ this.messageDiv.style.display="none";
+ this.messageShadow.hide();
+ },
+
+ showMsg: function(msg) {
+ this.messageDiv.innerHTML=RicoTranslate.getPhrase(msg);
+ this.messageDiv.style.display="";
+ var msgWidth=this.messageDiv.offsetWidth;
+ var msgHeight=this.messageDiv.offsetHeight;
+ var divwi=this.outerDiv.offsetWidth;
+ var divht=this.outerDiv.offsetHeight;
+ this.messageDiv.style.top=parseInt((divht-msgHeight)/2)+'px';
+ this.messageDiv.style.left=parseInt((divwi-msgWidth)/2)+'px';
+ this.messageShadow.show();
+ Rico.writeDebugMsg("showMsg: "+msg);
+ },
+
+ resetContents: function(resetHt) {
+ Rico.writeDebugMsg("resetContents("+resetHt+")");
+ this.buffer.clear();
+ this.clearRows();
+ if (typeof resetHt=='undefined' || resetHt==true) {
+ this.buffer.setTotalRows(0);
+ } else {
+ this.scrollToRow(0);
+ }
+ if (this.bookmark) this.bookmark.innerHTML=" ";
+ },
+
+ setImages: function() {
+ for (n=0; n<this.columns.length; n++)
+ this.columns[n].setImage();
+ },
+
+ // returns column index, or -1 if there are no sorted columns
+ findSortedColumn: function() {
+ for (var n=0; n<this.columns.length; n++)
+ if (this.columns[n].isSorted()) return n;
+ return -1;
+ },
+
+ findColumnName: function(name) {
+ for (var n=0; n<this.columns.length; n++)
+ if (this.columns[n].fieldName == name) return n;
+ return -1;
+ },
+
+/**
+ * Set initial sort
+ */
+ setSortUI: function( columnNameOrNum, sortDirection ) {
+ Rico.writeDebugMsg("setSortUI: "+columnNameOrNum+' '+sortDirection);
+ var colnum=this.findSortedColumn();
+ if (colnum >= 0) {
+ sortDirection=this.columns[colnum].getSortDirection();
+ } else {
+ if (typeof sortDirection!='string') {
+ sortDirection=Rico.TableColumn.SORT_ASC;
+ } else {
+ sortDirection=sortDirection.toUpperCase();
+ if (sortDirection != Rico.TableColumn.SORT_DESC) sortDirection=Rico.TableColumn.SORT_ASC;
+ }
+ switch (typeof columnNameOrNum) {
+ case 'string':
+ colnum=this.findColumnName(columnNameOrNum);
+ break;
+ case 'number':
+ colnum=columnNameOrNum;
+ break;
+ }
+ }
+ if (typeof(colnum)!='number' || colnum < 0) return;
+ this.clearSort();
+ this.columns[colnum].setSorted(sortDirection);
+ this.buffer.sortBuffer(colnum,sortDirection,this.columns[colnum].format.type,this.columns[colnum]._sortfunc);
+ },
+
+/**
+ * clear sort flag on all columns
+ */
+ clearSort: function() {
+ for (var x=0;x<this.columns.length;x++)
+ this.columns[x].setUnsorted();
+ },
+
+/**
+ * clear filters on all columns
+ */
+ clearFilters: function() {
+ for (var x=0;x<this.columns.length;x++)
+ this.columns[x].setUnfiltered(true);
+ if (this.options.filterHandler)
+ this.options.filterHandler();
+ },
+
+/**
+ * returns number of columns with a user filter set
+ */
+ filterCount: function() {
+ for (var x=0,cnt=0;x<this.columns.length;x++)
+ if (this.columns[x].isFiltered()) cnt++;
+ return cnt;
+ },
+
+ sortHandler: function() {
+ this.cancelMenu();
+ this.setImages();
+ var n=this.findSortedColumn();
+ if (n < 0) return;
+ Rico.writeDebugMsg("sortHandler: sorting column "+n);
+ this.buffer.sortBuffer(n,this.columns[n].getSortDirection(),this.columns[n].format.type,this.columns[n]._sortfunc);
+ this.clearRows();
+ this.scrollDiv.scrollTop = 0;
+ this.buffer.fetch(0);
+ },
+
+ filterHandler: function() {
+ Rico.writeDebugMsg("filterHandler");
+ this.cancelMenu();
+ this.ClearSelection();
+ this.setImages();
+ if (this.bookmark) this.bookmark.innerHTML=" ";
+ this.clearRows();
+ this.buffer.fetch(-1);
+ },
+
+ bookmarkHandler: function(firstrow,lastrow) {
+ if (isNaN(firstrow) || !this.bookmark) return;
+ var totrows=this.buffer.totalRows;
+ if (totrows < lastrow) lastrow=totrows;
+ if (totrows<=0) {
+ var newhtml = RicoTranslate.getPhrase("No matching records");
+ } else if (lastrow<0) {
+ var newhtml = RicoTranslate.getPhrase("No records");
+ } else {
+ var newhtml = RicoTranslate.getPhrase("Listing records")+" "+firstrow+" - "+lastrow;
+ var totphrase = this.buffer.foundRowCount ? "of" : "of about";
+ newhtml+=" "+RicoTranslate.getPhrase(totphrase)+" "+totrows;
+ }
+ this.bookmark.innerHTML = newhtml;
+ },
+
+/**
+ * @return array of column objects which have invisible status
+ */
+ listInvisible: function() {
+ var hiddenColumns=new Array();
+ for (var x=0;x<this.columns.length;x++)
+ if (this.columns[x].visible==false)
+ hiddenColumns.push(this.columns[x]);
+ return hiddenColumns;
+ },
+
+/**
+ * Show all columns
+ */
+ showAll: function() {
+ var invisible=this.listInvisible();
+ for (var x=0;x<invisible.length;x++)
+ invisible[x].showColumn();
+ },
+
+ clearRows: function() {
+ if (this.isBlank==true) return;
+ for (var c=0; c < this.columns.length; c++)
+ this.columns[c].clearColumn();
+ this.ClearSelection();
+ this.isBlank = true;
+ },
+
+ blankRow: function(r) {
+ for (var c=0; c < this.columns.length; c++)
+ this.columns[c].clearCell(r);
+ },
+
+ refreshContents: function(startPos) {
+ Rico.writeDebugMsg("refreshContents: startPos="+startPos+" lastRow="+this.lastRowPos+" PartBlank="+this.isPartialBlank+" pageSize="+this.pageSize);
+ this.hideMsg();
+ this.cancelMenu();
+ this.unhighlight(); // in case highlighting was manually invoked
+ this.highlightEnabled=this.options.highlightSection!='none';
+ if (startPos == this.lastRowPos && !this.isPartialBlank && !this.isBlank) return;
+ this.isBlank = false;
+ var viewPrecedesBuffer = this.buffer.startPos > startPos
+ var contentStartPos = viewPrecedesBuffer ? this.buffer.startPos: startPos;
+ var contentEndPos = Math.min(this.buffer.startPos + this.buffer.size, startPos + this.pageSize);
+ var onRefreshComplete = this.options.onRefreshComplete;
+
+ if ((startPos + this.pageSize < this.buffer.startPos)
+ || (this.buffer.startPos + this.buffer.size < startPos)
+ || (this.buffer.size == 0)) {
+ this.clearRows();
+ if (onRefreshComplete != null)
+ onRefreshComplete(contentStartPos+1,contentEndPos);
+ return;
+ }
+
+ Rico.writeDebugMsg('refreshContents: contentStartPos='+contentStartPos+' contentEndPos='+contentEndPos+' viewPrecedesBuffer='+viewPrecedesBuffer);
+ if (this.options.highlightElem=='selection') this.HideSelection();
+ var rowSize = contentEndPos - contentStartPos;
+ this.buffer.setWindow(contentStartPos, rowSize );
+ var blankSize = this.pageSize - rowSize;
+ var blankOffset = viewPrecedesBuffer ? 0: rowSize;
+ var contentOffset = viewPrecedesBuffer ? blankSize: 0;
+
+ for (var r=0; r < rowSize; r++) { //initialize what we have
+ for (var c=0; c < this.columns.length; c++)
+ this.columns[c].displayValue(r + contentOffset);
+ }
+ for (var i=0; i < blankSize; i++) // blank out the rest
+ this.blankRow(i + blankOffset);
+ if (this.options.highlightElem=='selection') this.ShowSelection();
+ this.isPartialBlank = blankSize > 0;
+ this.lastRowPos = startPos;
+ Rico.writeDebugMsg("refreshContents complete, startPos="+startPos);
+ // Check if user has set a onRefreshComplete function
+ if (onRefreshComplete != null)
+ onRefreshComplete(contentStartPos+1,contentEndPos);
+ },
+
+ scrollToRow: function(rowOffset) {
+ var p=this.rowToPixel(rowOffset);
+ Rico.writeDebugMsg("scrollToRow, rowOffset="+rowOffset+" pixel="+p);
+ this.scrollDiv.scrollTop = p; // this causes a scroll event
+ if ( this.options.onscroll )
+ this.options.onscroll( this, rowOffset );
+ },
+
+ scrollUp: function() {
+ this.moveRelative(-1);
+ },
+
+ scrollDown: function() {
+ this.moveRelative(1);
+ },
+
+ pageUp: function() {
+ this.moveRelative(-this.pageSize);
+ },
+
+ pageDown: function() {
+ this.moveRelative(this.pageSize);
+ },
+
+ adjustRow: function(rowOffset) {
+ var notdisp=this.topOfLastPage();
+ if (notdisp == 0 || !rowOffset) return 0;
+ return Math.min(notdisp,rowOffset);
+ },
+
+ rowToPixel: function(rowOffset) {
+ return this.adjustRow(rowOffset) * this.rowHeight;
+ },
+
+/**
+ * @returns row to display at top of scroll div
+ */
+ pixeltorow: function(p) {
+ var notdisp=this.topOfLastPage();
+ if (notdisp == 0) return 0;
+ var prow=parseInt(p/this.rowHeight);
+ return Math.min(notdisp,prow);
+ },
+
+ moveRelative: function(relOffset) {
+ newoffset=Math.max(this.scrollDiv.scrollTop+relOffset*this.rowHeight,0);
+ newoffset=Math.min(newoffset,this.scrollDiv.scrollHeight);
+ //Rico.writeDebugMsg("moveRelative, newoffset="+newoffset);
+ this.scrollDiv.scrollTop=newoffset;
+ },
+
+ pluginScroll: function() {
+ if (this.scrollPluggedIn) return;
+ Rico.writeDebugMsg("pluginScroll: wheelEvent="+this.wheelEvent);
+ Event.observe(this.scrollDiv,"scroll",this.scrollEventFunc, false);
+ for (var t=0; t<2; t++)
+ Event.observe(this.tabs[t],this.wheelEvent,this.wheelEventFunc, false);
+ this.scrollPluggedIn=true;
+ },
+
+ unplugScroll: function() {
+ if (!this.scrollPluggedIn) return;
+ Rico.writeDebugMsg("unplugScroll");
+ Event.stopObserving(this.scrollDiv,"scroll", this.scrollEventFunc , false);
+ for (var t=0; t<2; t++)
+ Event.stopObserving(this.tabs[t],this.wheelEvent,this.wheelEventFunc, false);
+ this.scrollPluggedIn=false;
+ },
+
+ handleWheel: function(e) {
+ var delta = 0;
+ if (e.wheelDelta) {
+ if (Prototype.Browser.Opera)
+ delta = e.wheelDelta/120;
+ else if (Prototype.Browser.WebKit)
+ delta = -e.wheelDelta/12;
+ else
+ delta = -e.wheelDelta/120;
+ } else if (e.detail) {
+ delta = e.detail/3; /* Mozilla/Gecko */
+ }
+ if (delta) this.moveRelative(delta);
+ Event.stop(e);
+ return false;
+ },
+
+ handleScroll: function(e) {
+ if ( this.scrollTimeout )
+ clearTimeout( this.scrollTimeout );
+ this.setHorizontalScroll();
+ var scrtop=this.scrollDiv.scrollTop;
+ var vscrollDiff = this.lastScrollPos-scrtop;
+ if (vscrollDiff == 0.00) return;
+ var newrow=this.pixeltorow(scrtop);
+ if (newrow == this.lastRowPos && !this.isPartialBlank && !this.isBlank) return;
+ var stamp1 = new Date();
+ //Rico.writeDebugMsg("handleScroll, newrow="+newrow+" scrtop="+scrtop);
+ this.buffer.fetch(newrow);
+ if (this.options.onscroll) this.options.onscroll(this, newrow);
+ this.scrollTimeout = setTimeout(this.scrollIdle.bind(this), 1200 );
+ this.lastScrollPos = this.scrollDiv.scrollTop;
+ var stamp2 = new Date();
+ //Rico.writeDebugMsg("handleScroll, time="+(stamp2.getTime()-stamp1.getTime()));
+ },
+
+ scrollIdle: function() {
+ if ( this.options.onscrollidle )
+ this.options.onscrollidle();
+ },
+
+ printAll: function(exportType) {
+ this.exportStart();
+ this.buffer.exportAllRows(this.exportBuffer.bind(this),this.exportFinish.bind(this,exportType));
+ },
+
+/**
+ * Send all rows to print window
+ */
+ exportBuffer: function(rows) {
+ for(var r=0; r < rows.length; r++) {
+ this.exportText+="<tr>";
+ for (var c=0; c<this.columns.length; c++) {
+ if (this.columns[c].visible)
+ this.exportText+="<td>"+this.columns[c]._format(rows[r][c].content)+"</td>";
+ }
+ this.exportText+="</tr>";
+ }
+ }
+
+};
+
+
+Object.extend(Rico.TableColumn.prototype, {
+
+initialize: function(liveGrid,colIdx,hdrInfo,tabIdx) {
+ this.baseInit(liveGrid,colIdx,hdrInfo,tabIdx);
+ Rico.writeDebugMsg(" sortable="+this.sortable+" filterable="+this.filterable+" hideable="+this.hideable+" isNullable="+this.isNullable+' isText='+this.isText);
+ this.fixHeaders(this.liveGrid.tableId, this.options.hdrIconsFirst);
+ if (this.format.type=='control' && this.format.control) {
+ // copy all properties/methods that start with '_'
+ if (typeof this.format.control=='string')
+ this.format.control=eval(this.format.control);
+ for (var property in this.format.control)
+ if (property.charAt(0)=='_') {
+ Rico.writeDebugMsg("Copying control property "+property);
+ this[property] = this.format.control[property];
+ }
+ } else if (this['format_'+this.format.type]) {
+ this._format=this['format_'+this.format.type].bind(this);
+ }
+},
+
+sortAsc: function() {
+ this.setColumnSort(Rico.TableColumn.SORT_ASC);
+},
+
+sortDesc: function() {
+ this.setColumnSort(Rico.TableColumn.SORT_DESC);
+},
+
+setColumnSort: function(direction) {
+ this.liveGrid.clearSort();
+ this.setSorted(direction);
+ if (this.liveGrid.options.saveColumnInfo.sort)
+ this.liveGrid.setCookie();
+ if (this.options.sortHandler)
+ this.options.sortHandler();
+},
+
+isSortable: function() {
+ return this.sortable;
+},
+
+isSorted: function() {
+ return this.currentSort != Rico.TableColumn.UNSORTED;
+},
+
+getSortDirection: function() {
+ return this.currentSort;
+},
+
+toggleSort: function() {
+ if (this.liveGrid.buffer && this.liveGrid.buffer.totalRows==0) return;
+ if (this.currentSort == Rico.TableColumn.SORT_ASC)
+ this.sortDesc();
+ else
+ this.sortAsc();
+},
+
+setUnsorted: function() {
+ this.setSorted(Rico.TableColumn.UNSORTED);
+},
+
+/**
+ * direction must be one of Rico.TableColumn.UNSORTED, .SORT_ASC, or .SORT_DESC
+ */
+setSorted: function(direction) {
+ this.currentSort = direction;
+},
+
+canFilter: function() {
+ return this.filterable;
+},
+
+getFilterText: function() {
+ var vals=[];
+ for (var i=0; i<this.filterValues.length; i++) {
+ var v=this.filterValues[i];
+ if (v!=null && v.match(/<span\s+class=(['"]?)ricolookup\1>(.*)<\/span>/i))
+ vals.push(RegExp.leftContext);
+ else
+ vals.push(v);
+ }
+ switch (this.filterOp) {
+ case 'EQ': return vals[0];
+ case 'NE': return 'not: '+vals.join(', ');
+ case 'LE': return '<= '+vals[0];
+ case 'GE': return '>= '+vals[0];
+ case 'LIKE': return 'like: '+vals[0];
+ case 'NULL': return '<empty>';
+ case 'NOTNULL': return '<not empty>';
+ }
+ return '?';
+},
+
+getFilterQueryParm: function() {
+ if (this.filterType == Rico.TableColumn.UNFILTERED) return '';
+ var retval='&f['+this.index+'][op]='+this.filterOp;
+ retval+='&f['+this.index+'][len]='+this.filterValues.length
+ for (var i=0; i<this.filterValues.length; i++)
+ retval+='&f['+this.index+']['+i+']='+escape(this.filterValues[i]);
+ return retval;
+},
+
+setUnfiltered: function(skipHandler) {
+ this.filterType = Rico.TableColumn.UNFILTERED;
+ if (this.liveGrid.options.saveColumnInfo.filter)
+ this.liveGrid.setCookie();
+ if (this.removeFilterFunc)
+ this.removeFilterFunc();
+ if (this.options.filterHandler && !skipHandler)
+ this.options.filterHandler();
+},
+
+setFilterEQ: function() {
+ if (this.userFilter=='' && this.isNullable)
+ this.setUserFilter('NULL');
+ else
+ this.setUserFilter('EQ');
+},
+setFilterNE: function() {
+ if (this.userFilter=='' && this.isNullable)
+ this.setUserFilter('NOTNULL');
+ else
+ this.setUserFilter('NE');
+},
+addFilterNE: function() {
+ this.filterValues.push(this.userFilter);
+ if (this.liveGrid.options.saveColumnInfo.filter)
+ this.liveGrid.setCookie();
+ if (this.options.filterHandler)
+ this.options.filterHandler();
+},
+setFilterGE: function() { this.setUserFilter('GE'); },
+setFilterLE: function() { this.setUserFilter('LE'); },
+setFilterKW: function() {
+ var keyword=prompt(RicoTranslate.getPhrase("Enter keyword to search for")+RicoTranslate.getPhrase(" (use * as a wildcard):"),'');
+ if (keyword!='' && keyword!=null) {
+ if (keyword.indexOf('*')==-1) keyword='*'+keyword+'*';
+ this.setFilter('LIKE',keyword,Rico.TableColumn.USERFILTER);
+ } else {
+ this.liveGrid.cancelMenu();
+ }
+},
+
+setUserFilter: function(relop) {
+ this.setFilter(relop,this.userFilter,Rico.TableColumn.USERFILTER);
+},
+
+setSystemFilter: function(relop,filter) {
+ this.setFilter(relop,filter,Rico.TableColumn.SYSTEMFILTER);
+},
+
+setFilter: function(relop,filter,type,removeFilterFunc) {
+ this.filterValues = [filter];
+ this.filterType = type;
+ this.filterOp = relop;
+ if (type == Rico.TableColumn.USERFILTER && this.liveGrid.options.saveColumnInfo.filter)
+ this.liveGrid.setCookie();
+ this.removeFilterFunc=removeFilterFunc;
+ if (this.options.filterHandler)
+ this.options.filterHandler();
+},
+
+isFiltered: function() {
+ return this.filterType == Rico.TableColumn.USERFILTER;
+},
+
+format_text: function(v) {
+ if (typeof v!='string')
+ return ' ';
+ else
+ return v.stripTags();
+},
+
+format_showTags: function(v) {
+ if (typeof v!='string')
+ return ' ';
+ else
+ return v.replace(/&/g, '&').replace(/</g,'<').replace(/>/g,'>');
+},
+
+format_number: function(v) {
+ if (typeof v=='undefined' || v=='' || v==null)
+ return ' ';
+ else
+ return v.formatNumber(this.format);
+},
+
+format_datetime: function(v) {
+ if (typeof v=='undefined' || v=='' || v==null)
+ return ' ';
+ else {
+ var d=new Date;
+ d.setISO8601(v);
+ return d.formatDate(this.format.dateFmt || 'translateDateTime');
+ }
+},
+
+format_date: function(v) {
+ if (typeof v=='undefined' || v==null || v=='')
+ return ' ';
+ else {
+ var d=new Date;
+ if (!d.setISO8601(v)) return v;
+ return d.formatDate(this.format.dateFmt || 'translateDate');
+ }
+},
+
+fixHeaders: function(prefix, iconsfirst) {
+ if (this.sortable) {
+ switch (this.options.headingSort) {
+ case 'link':
+ var a=RicoUtil.wrapChildren(this.hdrCellDiv,'ricoSort',undefined,'a')
+ a.href = "#";
+ a.onclick = this.toggleSort.bindAsEventListener(this);
+ break;
+ case 'hover':
+ this.hdrCellDiv.onclick = this.toggleSort.bindAsEventListener(this);
+ break;
+ }
+ }
+ this.imgFilter = document.createElement('img');
+ this.imgFilter.style.display='none';
+ this.imgFilter.src=Rico.imgDir+this.options.filterImg;
+ this.imgFilter.className='ricoLG_HdrIcon';
+ this.imgSort = document.createElement('img');
+ this.imgSort.style.display='none';
+ this.imgSort.className='ricoLG_HdrIcon';
+ if (iconsfirst) {
+ this.hdrCellDiv.insertBefore(this.imgSort,this.hdrCellDiv.firstChild);
+ this.hdrCellDiv.insertBefore(this.imgFilter,this.hdrCellDiv.firstChild);
+ } else {
+ this.hdrCellDiv.appendChild(this.imgFilter);
+ this.hdrCellDiv.appendChild(this.imgSort);
+ }
+},
+
+getValue: function(windowRow) {
+ return this.liveGrid.buffer.getWindowValue(windowRow,this.index);
+},
+
+getFormattedValue: function(windowRow) {
+ return this._format(this.getValue(windowRow));
+},
+
+getBufferCell: function(windowRow) {
+ return this.liveGrid.buffer.getWindowCell(windowRow,this.index);
+},
+
+setValue: function(windowRow,newval) {
+ this.liveGrid.buffer.setWindowValue(windowRow,this.index,newval);
+},
+
+_format: function(v) {
+ return v;
+},
+
+_display: function(v,gridCell) {
+ gridCell.innerHTML=this._format(v);
+},
+
+displayValue: function(windowRow) {
+ var bufCell=this.getBufferCell(windowRow);
+ if (!bufCell) {
+ this.clearCell(windowRow);
+ return;
+ }
+ var gridCell=this.cell(windowRow);
+ this._display(bufCell.content,gridCell,windowRow);
+ var acceptAttr=this.liveGrid.buffer.options.acceptAttr;
+ for (var k=0; k<acceptAttr.length; k++) {
+ var bufAttr=bufCell['_'+acceptAttr[k]] || '';
+ switch (acceptAttr[k]) {
+ case 'style': gridCell.style.cssText=bufAttr; break;
+ case 'class': gridCell.className=bufAttr; break;
+ default: gridCell['_'+acceptAttr[k]]=bufAttr; break;
+ }
+ }
+}
+
+});
+
+Rico.TableColumn.checkbox = Class.create();
+
+Rico.TableColumn.checkbox.prototype = {
+
+ initialize: function(checkedValue, uncheckedValue, defaultValue, readOnly) {
+ this._checkedValue=checkedValue;
+ this._uncheckedValue=uncheckedValue;
+ this._defaultValue=defaultValue || false;
+ this._readOnly=readOnly || false;
+ this._checkboxes=[];
+ },
+
+ _create: function(gridCell,windowRow) {
+ this._checkboxes[windowRow]=RicoUtil.createFormField(gridCell,'input','checkbox',this.liveGrid.tableId+'_chkbox_'+this.index+'_'+windowRow);
+ this._clear(gridCell,windowRow);
+ if (this._readOnly)
+ this._checkboxes[windowRow].disabled=true;
+ else
+ Event.observe(this._checkboxes[windowRow], "click", this._onclick.bindAsEventListener(this), false);
+ },
+
+ _onclick: function(e) {
+ var elem=Event.element(e);
+ var windowRow=parseInt(elem.id.split(/_/).pop());
+ var newval=elem.checked ? this._checkedValue : this._uncheckedValue;
+ this.setValue(windowRow,newval);
+ },
+
+ _clear: function(gridCell,windowRow) {
+ this._checkboxes[windowRow].checked=this._defaultValue;
+ },
+
+ _display: function(v,gridCell,windowRow) {
+ this._checkboxes[windowRow].checked=(v==this._checkedValue);
+ }
+
+}
+
+Rico.TableColumn.link = Class.create();
+
+Rico.TableColumn.link.prototype = {
+
+ initialize: function(href,target) {
+ this._href=href;
+ this._target=target;
+ this._anchors=[];
+ },
+
+ _create: function(gridCell,windowRow) {
+ this._anchors[windowRow]=RicoUtil.createFormField(gridCell,'a',null,this.liveGrid.tableId+'_a_'+this.index+'_'+windowRow);
+ if (this._target) this._anchors[windowRow].target=this._target;
+ this._clear(gridCell,windowRow);
+ },
+
+ _clear: function(gridCell,windowRow) {
+ this._anchors[windowRow].href='';
+ this._anchors[windowRow].innerHTML='';
+ },
+
+ _display: function(v,gridCell,windowRow) {
+ this._anchors[windowRow].innerHTML=v;
+ var getWindowValue=this.liveGrid.buffer.getWindowValue.bind(this.liveGrid.buffer);
+ this._anchors[windowRow].href=this._href.replace(/\{\d+\}/g,
+ function ($1) {
+ var colIdx=parseInt($1.substr(1));
+ return getWindowValue(windowRow,colIdx);
+ }
+ );
+ }
+
+}
+
+Rico.TableColumn.lookup = Class.create();
+
+Rico.TableColumn.lookup.prototype = {
+
+ initialize: function(map, defaultCode, defaultDesc) {
+ this._map=map;
+ this._defaultCode=defaultCode || '';
+ this._defaultDesc=defaultDesc || ' ';
+ this._sortfunc=this._sortvalue.bind(this);
+ this._codes=[];
+ this._descriptions=[];
+ },
+
+ _create: function(gridCell,windowRow) {
+ this._descriptions[windowRow]=RicoUtil.createFormField(gridCell,'span',null,this.liveGrid.tableId+'_desc_'+this.index+'_'+windowRow);
+ this._codes[windowRow]=RicoUtil.createFormField(gridCell,'input','hidden',this.liveGrid.tableId+'_code_'+this.index+'_'+windowRow);
+ this._clear(gridCell,windowRow);
+ },
+
+ _clear: function(gridCell,windowRow) {
+ this._codes[windowRow].value=this._defaultCode;
+ this._descriptions[windowRow].innerHTML=this._defaultDesc;
+ },
+
+ _sortvalue: function(v) {
+ return this._getdesc(v).replace(/&/g, '&').replace(/</g,'<').replace(/>/g,'>').replace(/ /g,' ');
+ },
+
+ _getdesc: function(v) {
+ var desc=this._map[v];
+ return (typeof desc=='string') ? desc : this._defaultDesc;
+ },
+
+ _display: function(v,gridCell,windowRow) {
+ this._codes[windowRow].value=v;
+ this._descriptions[windowRow].innerHTML=this._getdesc(v);
+ }
+
+}
+
+Rico.includeLoaded('ricoLiveGrid.js');
--- /dev/null
+if(typeof Rico=='undefined') throw("LiveGridAjax requires the Rico JavaScript framework");
+if(typeof RicoUtil=='undefined') throw("LiveGridAjax requires the RicoUtil object");
+if(typeof Rico.Buffer=='undefined') throw("LiveGridAjax requires the Rico.Buffer object");
+
+
+/**
+ * Data source is a static XML file located on the server
+ */
+Rico.Buffer.AjaxXML = Class.create();
+
+Rico.Buffer.AjaxXML.prototype = {
+
+ initialize: function(url,options,ajaxOptions) {
+ Object.extend(this, new Rico.Buffer.Base());
+ Object.extend(this, new Rico.Buffer.AjaxXMLMethods);
+ this.dataSource=url;
+ this.options.bufferTimeout = 20000; // time to wait for ajax response (milliseconds)
+ this.options.requestParameters = [];
+ Object.extend(this.options, options || {});
+ this.ajaxOptions = { parameters: null, method : 'get' };
+ Object.extend(this.ajaxOptions, ajaxOptions || {});
+ this.requestCount=0;
+ this.processingRequest=false;
+ this.pendingRequest=-1;
+ }
+}
+
+Rico.Buffer.AjaxXMLMethods = function() {};
+
+Rico.Buffer.AjaxXMLMethods.prototype = {
+
+ fetch: function(offset) {
+ if ( this.isInRange(offset) ) {
+ Rico.writeDebugMsg("AjaxXML fetch: in buffer");
+ this.liveGrid.refreshContents(offset);
+ return;
+ }
+ this.processingRequest=true
+ Rico.writeDebugMsg("AjaxXML fetch, offset="+offset);
+ this.liveGrid.showMsg("Waiting for data...");
+ this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout);
+ this.sendAjaxRequest(offset,0,this.ajaxUpdate.bind(this,offset));
+ },
+
+/**
+ * Server did not respond in time... assume that there could have been
+ * an error, and allow requests to be processed again.
+ */
+ handleTimedOut: function() {
+ Rico.writeDebugMsg("Request Timed Out");
+ this.liveGrid.showMsg("Request for data timed out!");
+ },
+
+ formQueryHash: function(startPos,fetchSize) {
+ if (typeof fetchSize!='number') fetchSize=this.totalRows;
+ var queryHash= {
+ id: this.liveGrid.tableId,
+ page_size: fetchSize,
+ offset: startPos
+ };
+ if (!this.foundRowCount) queryHash['get_total']='true';
+ if (this.options.requestParameters) {
+ for ( var i=0; i < this.options.requestParameters.length; i++ ) {
+ var anArg = this.options.requestParameters[i];
+ if ( anArg.name != undefined && anArg.value != undefined ) {
+ queryHash[anArg.name]=anArg.value;
+ } else {
+ var ePos = anArg.indexOf('=');
+ var argName = anArg.substring( 0, ePos );
+ var argValue = anArg.substring( ePos + 1 );
+ queryHash[argName]=argValue;
+ }
+ }
+ }
+
+ // sort
+ Object.extend(queryHash,this.sortParm);
+
+ // filters
+ for (n=0; n<this.liveGrid.columns.length; n++) {
+ var c=this.liveGrid.columns[n];
+ if (c.filterType == Rico.TableColumn.UNFILTERED) continue;
+ queryHash['f['+c.index+'][op]']=c.filterOp;
+ queryHash['f['+c.index+'][len]']=c.filterValues.length
+ for (var i=0; i<c.filterValues.length; i++)
+ queryHash['f['+c.index+']['+i+']']=c.filterValues[i];
+ }
+
+ return $H(queryHash);
+ },
+
+ sendAjaxRequest: function(startPos,fetchSize,onComplete) {
+ this.ajaxOptions.parameters = this.formQueryHash(startPos,fetchSize);
+ this.ajaxOptions.onComplete = onComplete;
+ this.requestCount++;
+ Rico.writeDebugMsg('req '+this.requestCount+':'+this.ajaxOptions.parameters.inspect());
+ new Ajax.Request(this.dataSource, this.ajaxOptions);
+ },
+
+ clearTimer: function() {
+ if(typeof this.timeoutHandler != "number") return;
+ window.clearTimeout(this.timeoutHandler);
+ delete this.timeoutHandler;
+ },
+
+ ajaxUpdate: function(startPos,request) {
+ this.clearTimer();
+ this.processingRequest=false;
+ if (request.status != 200) {
+ Rico.writeDebugMsg("ajaxUpdate: received http error="+request.status);
+ this.liveGrid.showMsg('Received HTTP error: '+request.status);
+ return;
+ }
+ var response = request.responseXML.getElementsByTagName("ajax-response");
+ if (response == null || response.length != 1) return;
+ this.updateBuffer(response[0],startPos);
+ this.CheckRowCount(response[0],startPos);
+ if (this.options.TimeOut && this.timerMsg)
+ this.restartSessionTimer();
+ if (this.options.onAjaxUpdate)
+ this.options.onAjaxUpdate();
+ if (this.pendingRequest>=0) {
+ var offset=this.pendingRequest;
+ Rico.writeDebugMsg("ajaxUpdate: found pending request for offset="+offset);
+ this.pendingRequest=-1;
+ this.fetch(offset);
+ }
+ },
+
+ CheckRowCount: function(ajaxResponse,offset) {
+ //try {
+ Rico.writeDebugMsg("CheckRowCount, size="+this.size+' rcv cnt type='+typeof(this.rowcntContent));
+ if (this.rcvdRowCount==true) {
+ Rico.writeDebugMsg("found row cnt: "+this.rowcntContent);
+ var eofrow=parseInt(this.rowcntContent);
+ var lastTotalRows=this.totalRows;
+ if (!isNaN(eofrow) && eofrow!=lastTotalRows) {
+ this.setTotalRows(eofrow);
+ var newpos=Math.min(this.liveGrid.topOfLastPage(),offset);
+ Rico.writeDebugMsg("CheckRowCount: new rowcnt="+eofrow+" newpos="+newpos);
+ if (lastTotalRows==0 && this.liveGrid.sizeTo=='data')
+ this.liveGrid.adjustPageSize();
+ //this.lastRowPos=-1;
+ this.liveGrid.scrollToRow(newpos);
+ if ( this.isInRange(newpos) ) {
+ this.liveGrid.refreshContents(newpos);
+ } else {
+ this.fetch(newpos);
+ }
+ return;
+ }
+ } else {
+ var lastbufrow=offset+this.rcvdRows;
+ if (lastbufrow>this.totalRows) {
+ var newcnt=lastbufrow;
+ Rico.writeDebugMsg("extending totrows to "+newcnt);
+ this.setTotalRows(newcnt);
+ }
+ }
+ var newpos=this.liveGrid.pixeltorow(this.liveGrid.scrollDiv.scrollTop);
+ Rico.writeDebugMsg("CheckRowCount: newpos="+newpos);
+ this.liveGrid.refreshContents(newpos);
+ //}
+ //catch(err) {
+ // alert("Error in CheckRowCount:"+err.message);
+ //}
+ },
+
+ updateBuffer: function(ajaxResponse, start) {
+ Rico.writeDebugMsg("updateBuffer: "+start);
+ this.rcvdRows = 0;
+ var newRows = this.loadRows(ajaxResponse);
+ if (newRows==null) return;
+ this.rcvdRows = newRows.length;
+ Rico.writeDebugMsg("updateBuffer: # of rows="+this.rcvdRows);
+ if (this.rows.length == 0) { // initial load
+ this.rows = newRows;
+ this.startPos = start;
+ } else 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.maxBufferSize && this.rows.length > this.maxBufferSize)
+ this.rows = this.rows.slice(0, this.maxBufferSize)
+ }
+ this.startPos = start;
+ }
+ this.size = this.rows.length;
+ },
+
+ loadRows: function(ajaxResponse) {
+ Rico.writeDebugMsg("loadRows");
+ this.rcvdRowCount = false;
+ var debugtags = ajaxResponse.getElementsByTagName('debug');
+ for (var i=0; i<debugtags.length; i++)
+ Rico.writeDebugMsg("loadRows, debug msg "+i+": "+RicoUtil.getContentAsString(debugtags[i],this.options.isEncoded));
+ var error = ajaxResponse.getElementsByTagName('error');
+ if (error.length > 0) {
+ var msg=RicoUtil.getContentAsString(error[0],this.options.isEncoded);
+ alert("Data provider returned an error:\n"+msg);
+ Rico.writeDebugMsg("Data provider returned an error:\n"+msg);
+ return null;
+ }
+ var rowsElement = ajaxResponse.getElementsByTagName('rows')[0];
+ var rowcnttags = ajaxResponse.getElementsByTagName('rowcount');
+ if (rowcnttags && rowcnttags.length==1) {
+ this.rowcntContent = RicoUtil.getContentAsString(rowcnttags[0],this.options.isEncoded);
+ this.rcvdRowCount = true;
+ this.foundRowCount = true;
+ Rico.writeDebugMsg("loadRows, found RowCount="+this.rowcntContent);
+ }
+ this.updateUI = rowsElement.getAttribute("update_ui") == "true";
+ this.rcvdOffset = rowsElement.getAttribute("offset");
+ Rico.writeDebugMsg("loadRows, rcvdOffset="+this.rcvdOffset);
+ return this.dom2jstable(rowsElement);
+ }
+
+};
+
+
+
+Rico.Buffer.AjaxSQL = Class.create();
+
+Rico.Buffer.AjaxSQL.prototype = {
+
+ initialize: function(url,options,ajaxOptions) {
+ Object.extend(this, new Rico.Buffer.AjaxXML());
+ Object.extend(this, new Rico.Buffer.AjaxSQLMethods());
+ this.dataSource=url;
+ this.options.canFilter=true;
+ this.options.largeBufferSize = 7.0; // 7 pages
+ this.options.nearLimitFactor = 1.0; // 1 page
+ Object.extend(this.options, options || {});
+ Object.extend(this.ajaxOptions, ajaxOptions || {});
+ this.sortParm={};
+ }
+}
+
+Rico.Buffer.AjaxSQLMethods = function() {};
+
+Rico.Buffer.AjaxSQLMethods.prototype = {
+
+ registerGrid: function(liveGrid) {
+ this.liveGrid = liveGrid;
+ this.sessionExpired=false;
+ this.timerMsg=$(liveGrid.tableId+'_timer');
+ if (this.options.TimeOut && this.timerMsg) {
+ if (!this.timerMsg.title) this.timerMsg.title=RicoTranslate.getPhrase("minutes before your session expires")
+ this.restartSessionTimer();
+ }
+ },
+
+ setBufferSize: function(pageSize) {
+ this.maxFetchSize = Math.max(50,parseInt(this.options.largeBufferSize * pageSize));
+ this.nearLimit = parseInt(this.options.nearLimitFactor * pageSize);
+ this.maxBufferSize = this.maxFetchSize * 3;
+ },
+
+ restartSessionTimer: function() {
+ if (this.sessionExpired==true) return;
+ this.timeRemaining=this.options.TimeOut+1;
+ if (this.sessionTimer) clearTimeout(this.sessionTimer);
+ this.updateSessionTimer();
+ },
+
+ updateSessionTimer: function() {
+ if (--this.timeRemaining<=0) {
+ this.displaySessionTimer(RicoTranslate.getPhrase("EXPIRED"));
+ this.timerMsg.style.backgroundColor="red";
+ this.sessionExpired=true;
+ } else {
+ this.displaySessionTimer(this.timeRemaining);
+ this.sessionTimer=setTimeout(this.updateSessionTimer.bind(this),60000);
+ }
+ },
+
+ displaySessionTimer: function(msg) {
+ this.timerMsg.innerHTML=' '+msg+' ';
+ },
+
+ refresh: function() {
+ this.fetch(this.lastOffset);
+ },
+
+ /**
+ * Fetch data from database.
+ * @param offset position (row) within the dataset (-1=clear existing buffer before issuing request)
+ */
+ fetch: function(offset) {
+ Rico.writeDebugMsg("AjaxSQL fetch, offset="+offset+' lastOffset='+this.lastOffset);
+ if (this.processingRequest) {
+ Rico.writeDebugMsg("AjaxSQL fetch: queue request");
+ this.pendingRequest=offset;
+ return;
+ }
+ if (offset < 0) {
+ this.clear();
+ this.setTotalRows(0);
+ this.foundRowCount = false;
+ offset=0;
+ }
+ var lastOffset = this.lastOffset;
+ this.lastOffset = offset;
+ var inRange=this.isInRange(offset);
+ if (inRange) {
+ Rico.writeDebugMsg("AjaxSQL fetch: in buffer");
+ this.liveGrid.refreshContents(offset);
+ if (offset > lastOffset) {
+ if (offset+this.liveGrid.pageSize < this.endPos()-this.nearLimit) return;
+ if (this.endPos()==this.totalRows && this.foundRowCount) return;
+ } else if (offset < lastOffset) {
+ if (offset > this.startPos+this.nearLimit) return;
+ if (this.startPos==0) return;
+ } else return;
+ }
+ if (offset >= this.totalRows && this.foundRowCount) return;
+
+ this.processingRequest=true
+ Rico.writeDebugMsg("AjaxSQL fetch, processing offset="+offset);
+ var bufferStartPos = this.getFetchOffset(offset);
+ var fetchSize = this.getFetchSize(bufferStartPos);
+ var partialLoaded = false;
+
+ if (!inRange) this.liveGrid.showMsg("Waiting for data...");
+ this.timeoutHandler = setTimeout( this.handleTimedOut.bind(this), this.options.bufferTimeout);
+ this.sendAjaxRequest(bufferStartPos,fetchSize,this.ajaxUpdate.bind(this,bufferStartPos));
+ },
+
+ getFetchSize: function(adjustedOffset) {
+ var adjustedSize = 0;
+ if (adjustedOffset >= this.startPos) { //appending
+ var endFetchOffset = this.maxFetchSize + adjustedOffset;
+ adjustedSize = endFetchOffset - adjustedOffset;
+ if(adjustedOffset == 0 && adjustedSize < this.maxFetchSize)
+ adjustedSize = this.maxFetchSize;
+ Rico.writeDebugMsg("getFetchSize/append, adjustedSize="+adjustedSize+" adjustedOffset="+adjustedOffset+' endFetchOffset='+endFetchOffset);
+ } else { //prepending
+ adjustedSize = Math.min(this.startPos - adjustedOffset,this.maxFetchSize);
+ }
+ return adjustedSize;
+ },
+
+ getFetchOffset: function(offset) {
+ var adjustedOffset = offset;
+ if (offset > this.startPos)
+ adjustedOffset = Math.max(offset, this.endPos()); //appending
+ else if (offset + this.maxFetchSize >= this.startPos)
+ adjustedOffset = Math.max(this.startPos - this.maxFetchSize, 0); //prepending
+ return adjustedOffset;
+ },
+
+ sortBuffer: function(colnum,sortdir,coltype) {
+ this.sortParm={};
+ if (this.options.sortParmFmt && this.options.sortParmFmt=='displayName') {
+ this.sortParm['sort_col']=this.liveGrid.columns[colnum].displayName.toLowerCase();
+ this.sortParm['sort_dir']=sortdir;
+ }else{
+ this.sortParm['s'+colnum]=sortdir;
+ }
+ this.clear();
+ },
+
+ exportAllRows: function(populate,finish) {
+ this.exportPopulate=populate;
+ this.exportFinish=finish;
+ this.liveGrid.showMsg("Waiting for data...");
+ this.sendExportRequest(0);
+ },
+
+/**
+ * Make ajax request for print window data
+ */
+ sendExportRequest: function(offset) {
+ this.timeoutHandler = setTimeout(this.exportTimedOut.bind(this), this.options.bufferTimeout);
+ this.sendAjaxRequest(offset,200,this.exportAppend.bind(this,offset));
+ },
+
+ exportTimedOut: function() {
+ Rico.writeDebugMsg("Print Request Timed Out");
+ this.liveGrid.showMsg("Request for data timed out!");
+ this.exportFinish();
+ },
+
+ exportAppend: function(startPos,request) {
+ this.clearTimer();
+ var response = request.responseXML.getElementsByTagName("ajax-response");
+ if (response == null || response.length != 1) return;
+ var rowsElement = response[0].getElementsByTagName('rows')[0];
+ var rows=this.dom2jstable(rowsElement);
+ this.exportPopulate(rows);
+ if (rows.length==0)
+ this.exportFinish();
+ else
+ this.sendExportRequest(startPos+rows.length);
+ }
+
+};
+
+Rico.includeLoaded('ricoLiveGridAjax.js');
--- /dev/null
+if(typeof Rico=='undefined') throw("LiveGridForms requires the Rico JavaScript framework");
+if(typeof RicoUtil=='undefined') throw("LiveGridForms requires the RicoUtil object");
+if(typeof RicoTranslate=='undefined') throw("LiveGridForms requires the RicoTranslate object");
+
+
+Rico.TableEdit = Class.create();
+
+Rico.TableEdit.prototype = {
+
+ initialize: function(liveGrid) {
+ Rico.writeDebugMsg('Rico.TableEdit initialize: '+liveGrid.tableId);
+ this.grid=liveGrid;
+ this.options = {
+ maxDisplayLen : 20, // max displayed text field length
+ panelHeight : 200, // size of tabbed panels
+ panelWidth : 500,
+ hoverClass : 'tabHover',
+ selectedClass : 'tabSelected',
+ compact : false, // compact corners
+ RecordName : 'record',
+ readOnlyColor : '#AAA', // read-only fields displayed using this color
+ showSaveMsg : 'errors' // disposition of database update responses (full - show full response, errors - show full response for errors and short response otherwise)
+ }
+ Object.extend(this.options, liveGrid.options);
+ this.menu=liveGrid.menu;
+ this.menu.options.dataMenuHandler=this.editMenu.bind(this);
+ this.menu.ignoreClicks();
+ RicoEditControls.atLoad();
+ this.createEditDiv();
+ this.saveMsg=$(liveGrid.tableId+'_savemsg');
+ Event.observe(document,"click", this.clearSaveMsg.bindAsEventListener(this), false);
+ this.TEerror=false;
+ this.extraMenuItems=new Array();
+ this.responseHandler=this.processResponse.bind(this);
+ },
+
+ createEditDiv: function() {
+
+ // create editDiv (form)
+
+ this.requestCount=1;
+ this.editDiv = this.grid.createDiv('edit',document.body);
+ this.editDiv.style.display='none';
+ if (this.options.canEdit || this.options.canAdd) {
+ this.startForm();
+ this.createForm(this.form);
+ } else {
+ var button=this.createButton("Close");
+ Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false);
+ this.createForm(this.editDiv);
+ }
+ this.editDivCreated=true;
+ this.formPopup=new Rico.Popup({ignoreClicks:true},this.editDiv);
+
+ // create responseDialog
+
+ this.responseDialog = this.grid.createDiv('editResponse',document.body);
+ this.responseDialog.style.display='none';
+
+ var button = document.createElement('button');
+ button.appendChild(document.createTextNode('OK'));
+ button.onclick=this.ackResponse.bindAsEventListener(this);
+ this.responseDialog.appendChild(button);
+
+ this.responseDiv = this.grid.createDiv('editResponseText',this.responseDialog);
+
+ if (this.panelGroup) {
+ Rico.writeDebugMsg("createEditDiv complete, requestCount="+this.requestCount);
+ setTimeout(this.initPanelGroup.bind(this),50);
+ }
+ },
+
+ initPanelGroup: function() {
+ this.requestCount--;
+ Rico.writeDebugMsg("initPanelGroup: "+this.requestCount);
+ if (this.requestCount>0) return;
+ var wi=parseInt(this.options.panelWidth);
+ this.form.style.width=(wi+10)+'px';
+ if (Prototype.Browser.WebKit) this.editDiv.style.display='block'; // this causes display to flash briefly
+ this.options.bgColor = Rico.Color.createColorFromBackground(this.form);
+ this.editDiv.style.display='none';
+ this.options.panelHdrWidth=(Math.floor(wi / this.options.panels.length)-4)+'px';
+ this.Accordion=new Rico.TabbedPanel(this.panelHdr.findAll(this.notEmpty), this.panelContent.findAll(this.notEmpty), this.options);
+ },
+
+ notEmpty: function(v) {
+ return typeof(v)!='undefined';
+ },
+
+ startForm: function() {
+ this.form = document.createElement('form');
+ this.form.onsubmit=function() {return false;};
+ this.editDiv.appendChild(this.form);
+
+ var tab = document.createElement('table');
+ var row = tab.insertRow(-1);
+ var cell = row.insertCell(-1);
+ var button=cell.appendChild(this.createButton("Save \t"+this.options.RecordName));
+ Event.observe(button,"click", this.TESubmit.bindAsEventListener(this), false);
+ var cell = row.insertCell(-1);
+ var button=cell.appendChild(this.createButton("Cancel"));
+ Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false);
+ this.form.appendChild(tab);
+
+ // hidden fields
+ this.hiddenFields = document.createElement('div');
+ this.hiddenFields.style.display='none';
+ this.action = this.appendHiddenField(this.grid.tableId+'__action','');
+ for (var i=0; i<this.grid.columns.length; i++) {
+ var fldSpec=this.grid.columns[i].format;
+ if (fldSpec && fldSpec.FormView && fldSpec.FormView=="hidden")
+ this.appendHiddenField(fldSpec.FieldName,fldSpec.ColData);
+ }
+ this.form.appendChild(this.hiddenFields);
+ },
+
+ createButton: function(buttonLabel) {
+ var button = document.createElement('button');
+ buttonLabel=RicoTranslate.getPhrase(buttonLabel);
+ button.innerHTML="<span style='text-decoration:underline;'>"+buttonLabel.charAt(0)+"</span>"+buttonLabel.substr(1);
+ button.accessKey=buttonLabel.charAt(0);
+ return button;
+ },
+
+ createPanel: function(i) {
+ var hasFields=false;
+ for (var j=0; j<this.grid.columns.length; j++) {
+ var fldSpec=this.grid.columns[j].format;
+ if (!fldSpec) continue;
+ if (!fldSpec.EntryType) continue
+ if (fldSpec.EntryType=='H') continue;
+ var panelIdx=fldSpec.panelIdx || 0;
+ if (panelIdx==i) {
+ hasFields=true;
+ break;
+ }
+ }
+ if (!hasFields) return false;
+ this.panelHdr[i] = document.createElement('div');
+ this.panelHdr[i].className='tabHeader';
+ this.panelHdr[i].innerHTML=this.options.panels[i];
+ this.panelHdrs.appendChild(this.panelHdr[i]);
+ this.panelContent[i] = document.createElement('div');
+ this.panelContent[i].className='tabContent';
+ this.panelContents.appendChild(this.panelContent[i]);
+ return true;
+ },
+
+ createForm: function(parentDiv) {
+ var tables=[];
+ this.panelHdr=[];
+ this.panelContent=[];
+ if (this.options.panels) {
+ this.panelGroup = document.createElement('div');
+ this.panelGroup.className='tabPanelGroup';
+ this.panelHdrs = document.createElement('div');
+ this.panelGroup.appendChild(this.panelHdrs);
+ this.panelContents = document.createElement('div');
+ this.panelContents.className='tabContentContainer';
+ this.panelGroup.appendChild(this.panelContents);
+ parentDiv.appendChild(this.panelGroup);
+ if (this.grid.direction=='rtl') {
+ for (var i=this.options.panels.length-1; i>=0; i--)
+ if (this.createPanel(i))
+ tables[i]=this.createFormTable(this.panelContent[i],'tabContent');
+ } else {
+ for (var i=0; i<this.options.panels.length; i++)
+ if (this.createPanel(i))
+ tables[i]=this.createFormTable(this.panelContent[i],'tabContent');
+ }
+ parentDiv.appendChild(this.panelGroup);
+ } else {
+ var div=document.createElement('div');
+ div.className='noTabContent';
+ tables[0]=this.createFormTable(div);
+ parentDiv.appendChild(div);
+ }
+ for (var i=0; i<this.grid.columns.length; i++) {
+ var fldSpec=this.grid.columns[i].format;
+ if (!fldSpec) continue;
+ var panelIdx=fldSpec.panelIdx || 0;
+ if (tables[panelIdx]) this.appendFormField(this.grid.columns[i],tables[panelIdx]);
+ }
+ },
+
+ createFormTable: function(div) {
+ var tab=document.createElement('table');
+ tab.border=0;
+ div.appendChild(tab);
+ return tab;
+ },
+
+ appendHiddenField: function(name,value) {
+ var field=RicoUtil.createFormField(this.hiddenFields,'input','hidden',name,name);
+ field.value=value;
+ return field;
+ },
+
+ appendFormField: function(column, table) {
+ if (!column.format.EntryType) return;
+ if (column.format.EntryType=="H") return;
+ if (column.format.FormView) return;
+ Rico.writeDebugMsg('appendFormField: '+column.format.Hdg+' - '+column.format.EntryType);
+ var row = table.insertRow(-1);
+ var hdr = row.insertCell(-1);
+ column.formLabel=hdr;
+ if (hdr.noWrap) hdr.noWrap=true;
+ var entry = row.insertCell(-1);
+ if (entry.noWrap) entry.noWrap=true;
+ hdr.innerHTML=column.format.Hdg;
+ hdr.className='ricoEditLabel';
+ if (column.format.Help) {
+ hdr.title=column.format.Help;
+ hdr.className='ricoEditLabelWithHelp';
+ }
+ var field, name=column.format.FieldName;
+ switch (column.format.EntryType) {
+ case 'TA','tinyMCE':
+ field=RicoUtil.createFormField(entry,'textarea',null,name);
+ field.cols=column.format.TxtAreaCols;
+ field.rows=column.format.TxtAreaRows;
+ field.innerHTML=column.format.ColData;
+ hdr.style.verticalAlign='top';
+ break;
+ case 'R':
+ case 'RL':
+ field=RicoUtil.createFormField(entry,'div',null,name);
+ if (column.format.isNullable)
+ this.addSelectOption(field,this.options.TableSelectNone,"(none)");
+ this.selectValuesRequest(field,column.format);
+ break;
+ case 'N':
+ field=RicoUtil.createFormField(entry,'select',null,name);
+ if (column.format.isNullable)
+ this.addSelectOption(field,this.options.TableSelectNone,"(none)");
+ field.onchange=this.checkSelectNew.bindAsEventListener(this);
+ this.selectValuesRequest(field,column.format);
+ field=document.createElement('span');
+ field.className='ricoEditLabel';
+ field.id='labelnew__'+column.format.FieldName;
+ field.innerHTML=' New value:';
+ entry.appendChild(field);
+ name='textnew__'+column.format.FieldName;
+ field=RicoUtil.createFormField(entry,'input','text',name,name);
+ break;
+ case 'S':
+ case 'SL':
+ field=RicoUtil.createFormField(entry,'select',null,name);
+ if (column.format.isNullable)
+ this.addSelectOption(field,this.options.TableSelectNone,"(none)");
+ this.selectValuesRequest(field,column.format);
+ break;
+ default:
+ field=RicoUtil.createFormField(entry,'input','text',name,name);
+ if (column.format.Length) {
+ field.maxLength=column.format.Length;
+ field.size=Math.min(column.format.Length, this.options.maxDisplayLen);
+ }
+ field.value=column.format.ColData;
+ break;
+ }
+ if (field) {
+ if (column.format.SelectCtl)
+ RicoEditControls.applyTo(column,field);
+ }
+ },
+
+ checkSelectNew: function(e) {
+ this.updateSelectNew(Event.element(e));
+ },
+
+ updateSelectNew: function(SelObj) {
+ var vis=(SelObj.value==this.options.TableSelectNew) ? "" : "hidden";
+ $("labelnew__" + SelObj.id).style.visibility=vis
+ $("textnew__" + SelObj.id).style.visibility=vis
+ },
+
+ selectValuesRequest: function(elem,fldSpec) {
+ if (fldSpec.SelectValues) {
+ var valueList=fldSpec.SelectValues.split(',');
+ for (var i=0; i<valueList.length; i++)
+ this.addSelectOption(elem,valueList[i],valueList[i],i);
+ } else {
+ this.requestCount++;
+ var options={};
+ Object.extend(options, this.grid.buffer.ajaxOptions);
+ options.parameters = 'id='+fldSpec.FieldName+'&offset=0&page_size=-1';
+ options.onComplete = this.selectValuesUpdate.bind(this);
+ new Ajax.Request(this.grid.buffer.dataSource, options);
+ Rico.writeDebugMsg("selectValuesRequest: "+options.parameters);
+ }
+ },
+
+ selectValuesUpdate: function(request) {
+ var response = request.responseXML.getElementsByTagName("ajax-response");
+ Rico.writeDebugMsg("selectValuesUpdate: "+request.status);
+ if (response == null || response.length != 1) return;
+ response=response[0];
+ var error = response.getElementsByTagName('error');
+ if (error.length > 0) {
+ Rico.writeDebugMsg("Data provider returned an error:\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded));
+ alert(RicoTranslate.getPhrase("The request returned an error")+":\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded));
+ return null;
+ }
+ response=response.getElementsByTagName('response')[0];
+ var id = response.getAttribute("id").slice(0,-8);
+ var rowsElement = response.getElementsByTagName('rows')[0];
+ var rows = this.grid.buffer.dom2jstable(rowsElement);
+ var elem=$(id);
+ //alert('selectValuesUpdate:'+id+' '+elem.tagName);
+ Rico.writeDebugMsg("selectValuesUpdate: id="+id+' rows='+rows.length);
+ for (var i=0; i<rows.length; i++) {
+ if (rows[i].length>0) {
+ var c0=rows[i][0].content;
+ var c1=(rows[i].length>1) ? rows[i][1].content : c0;
+ this.addSelectOption(elem,c0,c1,i);
+ }
+ }
+ if ($('textnew__'+id))
+ this.addSelectOption(elem,this.options.TableSelectNew,"(new value)");
+ if (this.panelGroup)
+ setTimeout(this.initPanelGroup.bind(this),50);
+ },
+
+ addSelectOption: function(elem,value,text,idx) {
+ switch (elem.tagName.toLowerCase()) {
+ case 'div':
+ var opt=RicoUtil.createFormField(elem,'input','radio',elem.id+'_'+idx,elem.id);
+ opt.value=value;
+ var lbl=document.createElement('label');
+ lbl.innerHTML=text;
+ lbl.htmlFor=opt.id;
+ elem.appendChild(lbl);
+ break;
+ case 'select':
+ var opt=document.createElement('option');
+ opt.value=value;
+ opt.text=text;
+ //elem.options.add(opt);
+ if (Prototype.Browser.IE)
+ elem.add(opt);
+ else
+ elem.add(opt,null);
+ break;
+ }
+ },
+
+ clearSaveMsg: function() {
+ if (this.saveMsg) this.saveMsg.innerHTML="";
+ },
+
+ addMenuItem: function(menuText,menuAction,enabled) {
+ this.extraMenuItems.push({menuText:menuText,menuAction:menuAction,enabled:enabled});
+ },
+
+ editMenu: function(grid,r,c,onBlankRow) {
+ this.clearSaveMsg();
+ if (this.grid.buffer.sessionExpired==true || this.grid.buffer.startPos<0) return;
+ this.rowIdx=r;
+ var elemTitle=$('pageTitle');
+ var pageTitle=elemTitle ? elemTitle.innerHTML : document.title;
+ this.menu.addMenuHeading(pageTitle);
+ for (var i=0; i<this.extraMenuItems.length; i++) {
+ this.menu.addMenuItem(this.extraMenuItems[i].menuText,this.extraMenuItems[i].menuAction,this.extraMenuItems[i].enabled);
+ }
+ if (onBlankRow==false) {
+ this.menu.addMenuItem("Edit\t this "+this.options.RecordName,this.editRecord.bindAsEventListener(this),this.options.canEdit);
+ this.menu.addMenuItem("Delete\t this "+this.options.RecordName,this.deleteRecord.bindAsEventListener(this),this.options.canDelete);
+ }
+ this.menu.addMenuItem("Add\t new "+this.options.RecordName,this.addRecord.bindAsEventListener(this),this.options.canAdd);
+ return true;
+ },
+
+ cancelEdit: function(e) {
+ Event.stop(e);
+ for (var i=0; i<this.grid.columns.length; i++)
+ if (this.grid.columns[i].format && this.grid.columns[i].format.SelectCtl)
+ RicoEditControls.close(this.grid.columns[i].format.SelectCtl);
+ this.makeFormInvisible();
+ this.grid.highlightEnabled=true;
+ this.menu.cancelmenu();
+ return false;
+ },
+
+ setField: function(fldSpec,fldvalue) {
+ var e=$(fldSpec.FieldName);
+ if (!e) return;
+ //alert('setField: '+fldSpec.FieldName+'='+fldvalue);
+ switch (e.tagName.toUpperCase()) {
+ case 'DIV':
+ var elems=e.getElementsByTagName('INPUT');
+ var fldcode=this.getLookupValue(fldvalue)[0];
+ for (var i=0; i<elems.length; i++)
+ elems[i].checked=(elems[i].value==fldcode);
+ break;
+ case 'INPUT':
+ if (fldSpec.SelectCtl)
+ fldvalue=this.getLookupValue(fldvalue)[0];
+ switch (e.type.toUpperCase()) {
+ case 'HIDDEN':
+ case 'TEXT':
+ e.value=fldvalue;
+ break;
+ }
+ break;
+ case 'SELECT':
+ var opts=e.options;
+ var fldcode=this.getLookupValue(fldvalue)[0];
+ //alert('setField SELECT: id='+e.id+'\nvalue='+fldcode+'\nopt cnt='+opts.length)
+ for (var i=0; i<opts.length; i++) {
+ if (opts[i].value==fldcode) {
+ e.selectedIndex=i;
+ break;
+ }
+ }
+ if (fldSpec.EntryType=='N') {
+ var txt=$('textnew__'+e.id);
+ if (!txt) alert('Warning: unable to find id "textnew__'+e.id+'"');
+ txt.value=fldvalue;
+ if (e.selectedIndex!=i) e.selectedIndex=opts.length-1;
+ this.updateSelectNew(e);
+ }
+ return;
+ case 'TEXTAREA':
+ e.value=fldvalue;
+ if (fldSpec.EntryType=='tinyMCE' && typeof(tinyMCE)!='undefined' && this.initialized)
+ tinyMCE.updateContent(e.id);
+ return;
+ }
+ },
+
+ getLookupValue: function(value) {
+ if (typeof value!='string')
+ return ['',''];
+ else if (value.match(/<span\s+class=(['"]?)ricolookup\1>(.*)<\/span>/i))
+ return [RegExp.$2,RegExp.leftContext];
+ else
+ return [value,value];
+ },
+
+ // use with care: Prototype 1.5 does not include disabled fields in the post-back
+ setReadOnly: function(addFlag) {
+ for (var i=0; i<this.grid.columns.length; i++) {
+ var fldSpec=this.grid.columns[i].format;
+ if (!fldSpec) continue;
+ var e=$(fldSpec.FieldName);
+ if (!e) continue;
+ var ro=!fldSpec.Writeable || fldSpec.ReadOnly || (fldSpec.InsertOnly && !addFlag) || (fldSpec.UpdateOnly && addFlag);
+ var color=ro ? this.options.readOnlyColor : '';
+ switch (e.tagName.toUpperCase()) {
+ case 'DIV':
+ var elems=e.getElementsByTagName('INPUT');
+ for (var j=0; j<elems.length; j++)
+ elems[j].disabled=ro;
+ break;
+ case 'SELECT':
+ if (fldSpec.EntryType=='N') {
+ var txt=$('textnew__'+e.id);
+ txt.disabled=ro;
+ }
+ e.disabled=ro;
+ break;
+ case 'TEXTAREA':
+ case 'INPUT':
+ e.readOnly=ro;
+ e.style.color=color;
+ if (fldSpec.selectIcon) fldSpec.selectIcon.style.display=ro ? 'none' : '';
+ break;
+ }
+ }
+ },
+
+ hideResponse: function(msg) {
+ this.responseDiv.innerHTML=msg;
+ this.responseDialog.style.display='none';
+ },
+
+ showResponse: function() {
+ var offset=Position.page(this.grid.outerDiv);
+ offset[1]+=RicoUtil.docScrollTop();
+ this.responseDialog.style.top=offset[1]+"px";
+ this.responseDialog.style.display='';
+ },
+
+ processResponse: function() {
+ var ch=this.responseDiv.childNodes;
+ for (var i=ch.length-1; i>=0; i--) {
+ if (ch[i].nodeType==1 && ch[i].nodeName!='P' && ch[i].nodeName!='DIV' && ch[i].nodeName!='BR')
+ this.responseDiv.removeChild(ch[i]);
+ }
+ var responseText=this.responseDiv.innerHTML;
+ if (responseText.toLowerCase().indexOf('error')==-1 && this.options.showSaveMsg!='full') {
+ this.hideResponse('');
+ this.grid.resetContents();
+ this.grid.buffer.foundRowCount = false;
+ this.grid.buffer.fetch(this.grid.lastRowPos || 0);
+ if (this.saveMsg) this.saveMsg.innerHTML=' '+responseText.stripTags()+' ';
+ }
+ this.processCallback(this.options.onSubmitResponse);
+ },
+
+ processCallback: function(callback) {
+ switch (typeof callback) {
+ case 'string': eval(callback); break;
+ case 'function': callback(); break;
+ }
+ },
+
+ // called when ok pressed on error response message
+ ackResponse: function() {
+ this.hideResponse('');
+ this.grid.highlightEnabled=true;
+ },
+
+ editRecord: function(e) {
+ this.grid.highlightEnabled=false;
+ this.menu.hidemenu();
+ this.hideResponse('Saving...');
+ this.grid.outerDiv.style.cursor = 'auto';
+ this.action.value="upd";
+ for (var i=0; i<this.grid.columns.length; i++) {
+ if (this.grid.columns[i].format) {
+ var v=this.grid.columns[i].getValue(this.rowIdx);
+ this.setField(this.grid.columns[i].format,v);
+ if (this.grid.columns[i].format.selectDesc)
+ this.grid.columns[i].format.selectDesc.innerHTML=this.grid.columns[i]._format(v);
+ }
+ }
+ this.setReadOnly(false);
+ this.key=this.getKey();
+ this.makeFormVisible(this.rowIdx);
+ },
+
+ addRecord: function() {
+ this.menu.hidemenu();
+ this.hideResponse('Saving...');
+ this.setReadOnly(true);
+ this.form.reset();
+ this.action.value="ins";
+ for (var i=0; i<this.grid.columns.length; i++) {
+ if (this.grid.columns[i].format) {
+ this.setField(this.grid.columns[i].format,this.grid.columns[i].format.ColData);
+ if (this.grid.columns[i].format.SelectCtl)
+ RicoEditControls.resetValue(this.grid.columns[i]);
+ }
+ }
+ this.key='';
+ this.makeFormVisible(-1);
+ if (this.Accordion) this.Accordion.selectionSet.selectIndex(0);
+ },
+
+ drillDown: function(e,masterColNum,detailColNum) {
+ var cell=Event.element(e || window.event);
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ this.grid.unhighlight();
+ var idx=this.grid.winCellIndex(cell);
+ this.grid.menuIdx=idx; // ensures selection gets cleared when menu is displayed
+ this.grid.highlight(idx);
+ var drillValue=this.grid.columns[masterColNum].getValue(idx.row);
+ for (var i=3; i<arguments.length; i++)
+ arguments[i].setDetailFilter(detailColNum,drillValue);
+ return idx.row;
+ },
+
+ // set filter on a detail grid that is in a master-detail relationship
+ setDetailFilter: function(colNumber,filterValue) {
+ var c=this.grid.columns[colNumber];
+ c.format.ColData=filterValue;
+ c.setSystemFilter('EQ',filterValue);
+ },
+
+ makeFormVisible: function(row) {
+ this.editDiv.style.display='block';
+
+ // set left position
+ var editWi=this.editDiv.offsetWidth;
+ var odOffset=Position.page(this.grid.outerDiv);
+ var winWi=RicoUtil.windowWidth();
+ if (editWi+odOffset[0] > winWi)
+ this.editDiv.style.left=(winWi-editWi)+'px';
+ else
+ this.editDiv.style.left=(odOffset[0]+1)+'px';
+
+ // set top position
+ var scrTop=RicoUtil.docScrollTop();
+ var editHt=this.editDiv.offsetHeight;
+ var newTop=odOffset[1]+this.grid.hdrHt+scrTop;
+ var bottom=RicoUtil.windowHeight()+scrTop;
+ if (row >= 0) {
+ newTop+=(row+1)*this.grid.rowHeight;
+ if (newTop+editHt>bottom) newTop-=(editHt+this.grid.rowHeight);
+ } else {
+ if (newTop+editHt>bottom) newTop=bottom-editHt;
+ }
+ this.processCallback(this.options.formOpen);
+ this.formPopup.openPopup(null,Math.max(newTop,scrTop));
+ this.editDiv.style.visibility='visible';
+ if (this.initialized) return;
+ for (i = 0; i < this.grid.columns.length; i++) {
+ spec=this.grid.columns[i].format;
+ if (!spec || !spec.EntryType || !spec.FieldName) continue;
+ switch (spec.EntryType) {
+ case 'tinyMCE':
+ if (typeof tinyMCE!='undefined') tinyMCE.execCommand('mceAddControl', true, spec.FieldName);
+ break;
+ }
+ }
+ this.formPopup.openPopup(); // tinyMCE may have changed the dimensions of the form
+ this.initialized=true;
+ },
+
+ makeFormInvisible: function() {
+ this.editDiv.style.visibility='hidden';
+ this.formPopup.closePopup();
+ this.processCallback(this.options.formClose);
+ },
+
+ getConfirmDesc: function(rowIdx) {
+ var desc=this.grid.columns[this.options.ConfirmDeleteCol].cell(rowIdx).innerHTML;
+ desc=this.getLookupValue(desc)[1];
+ return desc.stripTags();
+ },
+
+ deleteRecord: function() {
+ this.menu.hidemenu();
+ var desc;
+ if (this.options.ConfirmDeleteCol < 0) {
+ desc=RicoTranslate.getPhrase("this "+this.options.RecordName);
+ } else {
+ desc=this.getConfirmDesc(this.rowIdx);
+ if (desc.length>50) desc=desc.substring(0,50)+'...';
+ desc='\"' + desc + '\"'
+ }
+ if (!this.options.ConfirmDelete.valueOf || confirm(RicoTranslate.getPhrase("Are you sure you want to delete ") + desc + " ?")) {
+ this.hideResponse('Deleting...');
+ this.showResponse();
+ var parms=this.action.name+"=del"+this.getKey();
+ //alert(parms);
+ new Ajax.Updater(this.responseDiv, window.location.pathname, {parameters:parms,onComplete:this.processResponse.bind(this)});
+ }
+ this.menu.cancelmenu();
+ },
+
+ getKey: function() {
+ var key='';
+ for (var i=0; i<this.grid.columns.length; i++) {
+ if (this.grid.columns[i].format && this.grid.columns[i].format.isKey) {
+ var value=this.grid.columns[i].getValue(this.rowIdx);
+ value=this.getLookupValue(value)[0];
+ key+='&_k'+i+'='+value;
+ }
+ }
+ return key;
+ },
+
+ TESubmit: function(e) {
+ var i,lbl,spec,elem,entrytype;
+
+ if (!e) e=window.event;
+ Event.stop(e);
+
+ // check fields that are supposed to be non-blank
+
+ for (i = 0; i < this.grid.columns.length; i++) {
+ spec=this.grid.columns[i].format;
+ if (!spec || !spec.EntryType || !spec.FieldName) continue;
+ entrytype=spec.EntryType.charAt(0).toLowerCase();
+ if (!entrytype.match(/d|i|b/)) continue;
+ if (spec.isNullable==true && entrytype!='b') continue;
+ elem=$(spec.FieldName);
+ if (!elem) continue;
+ //alert("nonblank check: " + spec.FieldName);
+ if (elem.tagName.toLowerCase()!='input') continue;
+ if (elem.type.toLowerCase()!='text') continue;
+ if (elem.value.length == 0) {
+ alert(RicoTranslate.getPhrase("Please enter\t a value for")+" \"" + this.grid.columns[i].formLabel.innerHTML + "\"");
+ //setTimeout("FocusField(document." + this.form.name + "." + this.options.NonBlanks[i] + ")",2000);
+ return false;
+ }
+ }
+
+ // recheck any elements on the form with an onchange event
+
+ var InputFields = this.form.getElementsByTagName("input");
+ this.TEerror=false;
+ for (i=0; i < InputFields.length; i++) {
+ if (InputFields[i].type=="text" && InputFields[i].onchange) {
+ InputFields[i].onchange();
+ if (this.TEerror) return false;
+ }
+ }
+ if (typeof tinyMCE!='undefined') tinyMCE.triggerSave();
+ this.makeFormInvisible();
+ this.showResponse();
+ var parms=Form.serialize(this.form)+this.key
+ Rico.writeDebugMsg("TESubmit:"+parms);
+ new Ajax.Updater(this.responseDiv, window.location.pathname, {parameters:parms,onComplete:this.responseHandler});
+ this.menu.cancelmenu();
+ return false;
+ },
+
+ FocusField: function(elem) {
+ elem.focus();
+ elem.select();
+ },
+
+ TableEditCheckInt: function(TxtObj) {
+ var val=TxtObj.value;
+ if (val=='') return;
+ if (val!=parseInt(val)) {
+ alert(RicoTranslate.getPhrase("Please enter\t an integer value for")+" \"" + $("lbl_"+TxtObj.id).innerHTML + "\"");
+ setTimeout(this.FocusField.bind(this,TxtObj),0);
+ this.TEerror=true;
+ }
+ },
+
+ TableEditCheckPosInt: function(TxtObj) {
+ var val=TxtObj.value;
+ if (val=='') return;
+ if (val!=parseInt(val) || val<0) {
+ alert(RicoTranslate.getPhrase("Please enter\t a positive integer value for")+" \"" + $("lbl_"+TxtObj.id).innerHTML + "\"");
+ setTimeout(this.FocusField.bind(this,TxtObj),0);
+ this.TEerror=true;
+ }
+ }
+}
+
+
+// Registers custom popup widgets to fill in a text box (e.g. ricoCalendar and ricoTree)
+//
+// Custom widget must implement:
+// open() method (make control visible)
+// close() method (hide control)
+// container property (div element that contains the control)
+// id property (uniquely identifies the widget class)
+//
+// widget calls returnValue method to return a value to the caller
+//
+// this object handles clicks on the control's icon and positions the control appropriately.
+var RicoEditControls = {
+ widgetList:$H(),
+ elemList:$H(),
+
+ register: function(widget, imgsrc) {
+ var tmp={};
+ tmp[widget.id]={imgsrc:imgsrc, widget:widget, currentEl:''};
+ this.widgetList=this.widgetList.merge(tmp);
+ widget.returnValue=this.setValue.bind(this,widget);
+ Rico.writeDebugMsg("RicoEditControls.register:"+widget.id);
+ },
+
+ atLoad: function() {
+ var k=this.widgetList.keys();
+ for (var i=0; i<k.length; i++) {
+ var w=this.widgetList[k[i]].widget;
+ if (w.atLoad) w.atLoad();
+ }
+ },
+
+ applyTo: function(column,inputCtl) {
+ var wInfo=this.widgetList[column.format.SelectCtl];
+ if (!wInfo) return null;
+ Rico.writeDebugMsg('RicoEditControls.applyTo: '+column.displayName+' : '+column.format.SelectCtl);
+ var descSpan = document.createElement('span');
+ var newimg = document.createElement('img');
+ newimg.style.paddingLeft='4px';
+ newimg.style.cursor='pointer';
+ newimg.align='top';
+ newimg.src=wInfo.imgsrc;
+ newimg.id=this.imgId(column.format.FieldName);
+ newimg.onclick=this.processClick.bindAsEventListener(this);
+ inputCtl.parentNode.appendChild(descSpan);
+ inputCtl.parentNode.appendChild(newimg);
+ inputCtl.style.display='none'; // comment out this line for debugging
+ var tmp=new Object();
+ tmp[newimg.id]={descSpan:descSpan, inputCtl:inputCtl, widget:wInfo.widget, listObj:wInfo, column:column};
+ this.elemList=this.elemList.merge(tmp);
+ column.format.selectIcon=newimg;
+ column.format.selectDesc=descSpan;
+ },
+
+ processClick: function(e) {
+ var elem=Event.element(e);
+ var el=this.elemList[elem.id];
+ if (!el) return;
+ if (el.listObj.currentEl==elem.id && el.widget.container.style.display!='none') {
+ el.widget.close();
+ el.listObj.currentEl='';
+ } else {
+ el.listObj.currentEl=elem.id;
+ Rico.writeDebugMsg('RicoEditControls.processClick: '+el.widget.id+' : '+el.inputCtl.value);
+ RicoUtil.positionCtlOverIcon(el.widget.container,elem);
+ el.widget.open(el.inputCtl.value);
+ }
+ },
+
+ imgId: function(fieldname) {
+ return 'icon_'+fieldname;
+ },
+
+ resetValue: function(column) {
+ var el=this.elemList[this.imgId(column.format.FieldName)];
+ if (!el) return;
+ el.inputCtl.value=column.format.ColData;
+ el.descSpan.innerHTML=column._format(column.format.ColData);
+ },
+
+ setValue: function(widget,newVal,newDesc) {
+ var wInfo=this.widgetList[widget.id];
+ if (!wInfo) return null;
+ var id=wInfo.currentEl;
+ if (!id) return null;
+ var el=this.elemList[id];
+ if (!el) return null;
+ el.inputCtl.value=newVal;
+ if (!newDesc) newDesc=el.column._format(newVal);
+ el.descSpan.innerHTML=newDesc;
+ //alert(widget.id+':'+id+':'+el.inputCtl.id+':'+el.inputCtl.value+':'+newDesc);
+ },
+
+ close: function(id) {
+ var wInfo=this.widgetList[id];
+ if (!wInfo) return;
+ if (wInfo.widget.container.style.display!='none')
+ wInfo.widget.close();
+ }
+}
+
+Rico.includeLoaded('ricoLiveGridForms.js');
--- /dev/null
+if(typeof Rico=='undefined')
+ throw("GridMenu requires the Rico JavaScript framework");
+
+
+/**
+ * Standard menu for LiveGrid
+ */
+Rico.GridMenu = Class.create();
+
+Rico.GridMenu.prototype = {
+
+initialize: function(options) {
+ this.options = {
+ width : '20em',
+ dataMenuHandler : null // put custom items on the menu
+ };
+ Object.extend(this.options, options || {});
+ Object.extend(this, new Rico.Menu(this.options));
+ this.sortmenu = new Rico.Menu(this.options);
+ this.filtermenu = new Rico.Menu(this.options);
+ this.exportmenu = new Rico.Menu(this.options);
+ this.hideshowmenu = new Rico.Menu(this.options);
+ this.createDiv();
+ this.sortmenu.createDiv();
+ this.filtermenu.createDiv();
+ this.exportmenu.createDiv();
+ this.hideshowmenu.createDiv();
+},
+
+// Build context menu for grid
+buildGridMenu: function(r,c) {
+ this.clearMenu();
+ var totrows=this.liveGrid.buffer.totalRows;
+ var onBlankRow=r >= totrows;
+ var column=this.liveGrid.columns[c];
+ if (this.options.dataMenuHandler) {
+ var showMenu=this.options.dataMenuHandler(this.liveGrid,r,c,onBlankRow);
+ if (!showMenu) return false;
+ }
+
+ // menu items for sorting
+ if (column.sortable && totrows>0) {
+ this.sortmenu.clearMenu();
+ this.addSubMenuItem(RicoTranslate.getPhrase("Sort by")+": "+column.displayName, this.sortmenu, false);
+ this.sortmenu.addMenuItem("Ascending", column.sortAsc.bind(column), true);
+ this.sortmenu.addMenuItem("Descending", column.sortDesc.bind(column), true);
+ }
+
+ // menu items for filtering
+ if (column.canFilter() && (!onBlankRow || column.filterType == Rico.TableColumn.USERFILTER)) {
+ this.filtermenu.clearMenu();
+ this.addSubMenuItem(RicoTranslate.getPhrase("Filter by")+": "+column.displayName, this.filtermenu, false);
+ column.userFilter=column.getValue(r);
+ if (column.filterType == Rico.TableColumn.USERFILTER) {
+ this.filtermenu.addMenuItem("Remove filter", column.setUnfiltered.bind(column), true);
+ this.filtermenu.addMenuItem("Refresh", this.liveGrid.filterHandler.bind(this.liveGrid), true);
+ if (column.filterOp=='LIKE')
+ this.filtermenu.addMenuItem("Change keyword...", column.setFilterKW.bind(column), true);
+ if (column.filterOp=='NE' && !onBlankRow)
+ this.filtermenu.addMenuItem("Exclude this value also", column.addFilterNE.bind(column), true);
+ } else if (!onBlankRow) {
+ this.filtermenu.addMenuItem("Include only this value", column.setFilterEQ.bind(column), true);
+ this.filtermenu.addMenuItem("Greater than or equal to this value", column.setFilterGE.bind(column), column.userFilter!='');
+ this.filtermenu.addMenuItem("Less than or equal to this value", column.setFilterLE.bind(column), column.userFilter!='');
+ if (column.isText)
+ this.filtermenu.addMenuItem("Contains keyword...", column.setFilterKW.bind(column), true);
+ this.filtermenu.addMenuItem("Exclude this value", column.setFilterNE.bind(column), true);
+ }
+ if (this.liveGrid.filterCount() > 0)
+ this.filtermenu.addMenuItem("Remove all filters", this.liveGrid.clearFilters.bind(this.liveGrid), true);
+ }
+
+ // menu items for Print/Export
+ if (this.liveGrid.options.maxPrint > 0 && totrows>0) {
+ this.exportmenu.clearMenu();
+ this.addSubMenuItem('Print\t/Export',this.exportmenu);
+ this.exportmenu.addMenuItem("Visible rows to web page", this.liveGrid.printVisible.bind(this.liveGrid,'plain'), true);
+ this.exportmenu.addMenuItem("All rows to web page", this.liveGrid.printAll.bind(this.liveGrid,'plain'), this.liveGrid.buffer.totalRows <= this.liveGrid.options.maxPrint);
+ if (Prototype.Browser.IE) {
+ this.exportmenu.addMenuBreak();
+ this.exportmenu.addMenuItem("Visible rows to spreadsheet", this.liveGrid.printVisible.bind(this.liveGrid,'owc'), true);
+ this.exportmenu.addMenuItem("All rows to spreadsheet", this.liveGrid.printAll.bind(this.liveGrid,'owc'), this.liveGrid.buffer.totalRows <= this.liveGrid.options.maxPrint);
+ }
+ }
+
+ // menu items for hide/unhide
+ var hiddenCols=this.liveGrid.listInvisible();
+ for (var showableCnt=0,x=0; x<hiddenCols.length; x++)
+ if (hiddenCols[x].canHideShow()) showableCnt++;
+ if (showableCnt > 0 || column.canHideShow()) {
+ this.hideshowmenu.clearMenu();
+ this.addSubMenuItem('Hide\t/Show',this.hideshowmenu);
+ var visibleCnt=this.liveGrid.columns.length-hiddenCols.length;
+ var enabled=(visibleCnt>1 && column.visible && column.canHideShow());
+ this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Hide')+': '+column.displayName, column.hideColumn.bind(column), enabled);
+ for (var cnt=0,x=0; x<hiddenCols.length; x++) {
+ if (hiddenCols[x].canHideShow()) {
+ if (cnt++==0) this.hideshowmenu.addMenuBreak();
+ this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Show')+': '+hiddenCols[x].displayName, hiddenCols[x].showColumn.bind(hiddenCols[x]));
+ }
+ }
+ if (hiddenCols.length > 1)
+ this.hideshowmenu.addMenuItem(RicoTranslate.getPhrase('Show All'), this.liveGrid.showAll.bind(this.liveGrid));
+ }
+ return true;
+}
+
+}
+
+Rico.includeLoaded('ricoLiveGridMenu.js');
--- /dev/null
+Rico.Menu = Class.create();
+
+Rico.Menu.prototype = {
+
+ initialize: function(options) {
+ Object.extend(this, new Rico.Popup());
+ Object.extend(this.options, {
+ width : "15em",
+ margin : 6 // account for shadow
+ });
+ if (typeof options=='string')
+ this.options.width=options;
+ else
+ Object.extend(this.options, options || {});
+ this.hideFunc=null;
+ this.highlightElem=null;
+ new Image().src = Rico.imgDir+'left.gif';
+ new Image().src = Rico.imgDir+'right.gif';
+ },
+
+ createDiv: function(parentNode) {
+ if (this.div) return;
+ this.div = document.createElement('div');
+ this.div.className = Prototype.Browser.WebKit ? 'ricoMenuSafari' : 'ricoMenu';
+ this.div.style.position="absolute";
+ this.div.style.width=this.options.width;
+ if (!parentNode) parentNode = document.getElementsByTagName("body")[0];
+ parentNode.appendChild(this.div);
+ this.width=this.div.offsetWidth
+ this.setDiv(this.div,this.cancelmenu.bindAsEventListener(this));
+ this.direction=Element.getStyle(this.div,'direction') || 'ltr';
+ this.direction=this.direction.toLowerCase(); // ltr or rtl
+ this.hidemenu();
+ this.itemCount=0;
+ },
+
+ showmenu: function(e,hideFunc){
+ Event.stop(e);
+ this.hideFunc=hideFunc;
+ if (this.div.childNodes.length==0) {
+ this.cancelmenu();
+ return false;
+ }
+ this.openmenu(e.clientX,e.clientY,0,0);
+ },
+
+ openmenu: function(x,y,clickItemWi,clickItemHt) {
+ var newLeft=RicoUtil.docScrollLeft()+x;
+ //window.status='openmenu: newLeft='+newLeft+' width='+this.width+' windowWi='+RicoUtil.windowWidth();
+ if (this.direction == 'rtl') {
+ if (newLeft > this.width+clickItemWi) newLeft-=this.width+clickItemWi;
+ } else {
+ if (x+this.width+this.options.margin > RicoUtil.windowWidth()) newLeft-=this.width+clickItemWi;
+ }
+ var newTop=RicoUtil.docScrollTop()+y;
+ this.div.style.visibility="hidden";
+ this.div.style.display="block";
+ var contentHt=this.div.offsetHeight;
+ if (y+contentHt+this.options.margin > RicoUtil.windowHeight())
+ newTop=Math.max(newTop-contentHt+clickItemHt,0);
+ this.openPopup(newLeft,newTop);
+ this.div.style.visibility ="visible";
+ return false;
+ },
+
+ clearMenu: function() {
+ this.div.innerHTML="";
+ this.defaultAction=null;
+ this.itemCount=0;
+ },
+
+ addMenuHeading: function(hdg,translate) {
+ var el=document.createElement('div')
+ el.innerHTML =(translate==null || translate==true) ? RicoTranslate.getPhrase(hdg) : hdg;
+ el.className='ricoMenuHeading';
+ this.div.appendChild(el);
+ },
+
+ addMenuBreak: function() {
+ var brk=document.createElement('div');
+ brk.className="ricoMenuBreak";
+ this.div.appendChild(brk);
+ },
+
+ addSubMenuItem: function(menutext, submenu, translate) {
+ var dir=this.direction=='rtl' ? 'left' : 'right';
+ var a=this.addMenuItem(menutext,null,true,null,translate);
+ a.className='ricoSubMenu';
+ a.style.backgroundImage='url('+Rico.imgDir+dir+'.gif)';
+ a.style.backgroundRepeat='no-repeat';
+ a.style.backgroundPosition=dir;
+ a.onmouseover=this.showSubMenu.bind(this,a,submenu);
+ a.onmouseout=this.subMenuOut.bindAsEventListener(this);
+ },
+
+ showSubMenu: function(a,submenu) {
+ if (this.openSubMenu) this.hideSubMenu();
+ this.openSubMenu=submenu;
+ this.openMenuAnchor=a;
+ var pos=Position.page(a);
+ if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen';
+ submenu.openmenu(pos[0]+a.offsetWidth, pos[1], a.offsetWidth-2, a.offsetHeight+2);
+ },
+
+ subMenuOut: function(e) {
+ if (!this.openSubMenu) return;
+ Event.stop(e);
+ var elem=Event.element(e);
+ var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
+ try {
+ while (reltg != null && reltg != this.openSubMenu.div)
+ reltg=reltg.parentNode;
+ } catch(err) {}
+ if (reltg == this.openSubMenu.div) return;
+ this.hideSubMenu();
+ },
+
+ hideSubMenu: function() {
+ if (this.openMenuAnchor) {
+ this.openMenuAnchor.className='ricoSubMenu';
+ this.openMenuAnchor=null;
+ }
+ if (this.openSubMenu) {
+ this.openSubMenu.hidemenu();
+ this.openSubMenu=null;
+ }
+ },
+
+ addMenuItem: function(menutext,action,enabled,title,translate,target) {
+ this.itemCount++;
+ if (translate==null) translate=true;
+ var a = document.createElement(typeof action=='string' ? 'a' : 'div');
+ if ( arguments.length < 3 || enabled ) {
+ switch (typeof action) {
+ case 'function':
+ a.onclick = action;
+ break;
+ case 'string' :
+ a.href = action;
+ if (target) a.target = target;
+ break
+ }
+ a.className = 'enabled';
+ if (this.defaultAction==null) this.defaultAction=action;
+ } else {
+ a.disabled = true;
+ a.className = 'disabled';
+ }
+ a.innerHTML = translate ? RicoTranslate.getPhrase(menutext) : menutext;
+ if (typeof title=='string')
+ a.title = translate ? RicoTranslate.getPhrase(title) : title;
+ a=this.div.appendChild(a);
+ Event.observe(a,"mouseover", this.mouseOver.bindAsEventListener(this));
+ Event.observe(a,"mouseout", this.mouseOut.bindAsEventListener(this));
+ return a;
+ },
+
+ mouseOver: function(e) {
+ if (this.highlightElem && this.highlightElem.className=='enabled-hover') {
+ // required for Safari
+ this.highlightElem.className='enabled';
+ this.highlightElem=null;
+ }
+ var elem=Event.element(e);
+ if (this.openMenuAnchor && this.openMenuAnchor!=elem)
+ this.hideSubMenu();
+ if (elem.className=='enabled') {
+ elem.className='enabled-hover';
+ this.highlightElem=elem;
+ }
+ },
+
+ mouseOut: function(e) {
+ var elem=Event.element(e);
+ if (elem.className=='enabled-hover') elem.className='enabled';
+ if (this.highlightElem==elem) this.highlightElem=null;
+ },
+
+ isVisible: function() {
+ return this.div && Element.visible(this.div);
+ },
+
+ cancelmenu: function() {
+ if (this.hideFunc) this.hideFunc();
+ this.hideFunc=null;
+ this.hidemenu();
+ },
+
+ hidemenu: function() {
+ if (!this.div) return;
+ if (this.openSubMenu) this.openSubMenu.hidemenu();
+ this.closePopup();
+ }
+
+};
+
+Rico.includeLoaded('ricoMenu.js');
--- /dev/null
+Object.extend(Rico.SimpleGrid.prototype, {
+
+initSheet: function() {
+ this.highlightDiv=[];
+ for (var i=0; i<4; i++) {
+ this.highlightDiv[i] = this.createDiv("highlight",this.scrollDiv);
+ this.highlightDiv[i].style.display="none";
+ this.highlightDiv[i].id+=i;
+ this.highlightDiv[i].style[i % 2==0 ? 'height' : 'width']="0px";
+ }
+ for (var c=1; c<this.columns.length; c++) {
+ var col=this.columns[c];
+ for (var r=0; r<col.numRows(); r++) {
+ var cell=col.cell(r);
+ cell.RicoRow=r+1;
+ cell.RicoCol=c;
+ cell.RicoValue=null;
+ }
+ }
+ if (this.menu) {
+ if (!this.menu.grid) this.registerScrollMenu(this.menu);
+ this.menu.showmenu=this.menu.showSheetMenu;
+ }
+ this.inputArea=RicoUtil.createFormField(this.scrollDiv,'textarea',null,'inputArea');
+ this.inputArea.style.position='absolute';
+ this.inputArea.style.display='none';
+ this.inputArea.style.zIndex=2;
+ this.inputArea.cols=30;
+ this.inputArea.rows=4;
+ this.inputArea.blur();
+ this.clipBox=RicoUtil.createFormField(this.innerDiv,'textarea',null,'clipBox');
+ this.clipBox.style.position='absolute';
+ this.clipBox.style.display='none';
+ this.clipBox.cols=80;
+ this.clipBox.rows=10;
+ this.clipBox.style.top='0px';
+ this.clipBox.style.left='0px';
+ this.selectCellRC(0,1);
+ this.mouseOverHandler = this.selectMouseOver.bindAsEventListener(this);
+ this.mouseUpHandler = this.selectMouseUp.bindAsEventListener(this);
+ Event.observe(this.inputArea,'keydown',this.inputKeydown.bindAsEventListener(this),false);
+ Event.observe(Prototype.Browser.IE ? document.body : window,'keydown',this.gridKeydown.bindAsEventListener(this),false);
+ Event.observe(this.tbody[1],"mousedown", this.selectMouseDown.bindAsEventListener(this), false);
+
+ // disable drag & select events in IE
+ this.outerDiv.ondrag = this.disableEvent;
+ this.outerDiv.onselectstart = this.disableEvent;
+ this.tbody[1].ondrag = this.disableEvent;
+ this.tbody[1].onselectstart = this.disableEvent;
+},
+
+disableEvent: function(e) {
+ e=e || event;
+ Event.stop(e);
+ return false;
+},
+
+cellIndex: function(cell) {
+ var a=cell.id.split(/_/);
+ var l=a.length;
+ var r=parseInt(a[l-2]);
+ var c=parseInt(a[l-1]);
+ return {row:r, column:c, tabIdx:this.columns[c].tabIdx, cell:cell};
+},
+
+AdjustSelection: function(cell) {
+ var newIdx=this.cellIndex(cell);
+ if (this.SelectIdxStart.tabIdx != newIdx.tabIdx) return;
+ this.HideSelection();
+ this.SelectIdxEnd=newIdx;
+ this.ShowSelection();
+},
+
+selectMouseDown: function(e) {
+ if (this.highlightEnabled==false) return true;
+ this.cancelMenu();
+ var cell=Event.element(e);
+ Event.stop(e);
+ if (!Event.isLeftClick(e)) return;
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ var newIdx=this.cellIndex(cell);
+ if (e.shiftKey) {
+ if (!this.SelectIdxStart) return;
+ this.selectCellRC(newIdx.row,newIdx.column,true);
+ } else {
+ this.selectCellRC(newIdx.row,newIdx.column,false);
+ this.pluginSelect();
+ }
+},
+
+pluginSelect: function() {
+ if (this.selectPluggedIn) return;
+ var tBody=this.tbody[this.SelectIdxStart.tabIdx];
+ Event.observe(tBody,"mouseover", this.mouseOverHandler, false);
+ Event.observe(this.outerDiv,"mouseup", this.mouseUpHandler, false);
+ this.selectPluggedIn=true;
+},
+
+unplugSelect: function() {
+ var tBody=this.tbody[this.SelectIdxStart.tabIdx];
+ Event.stopObserving(tBody,"mouseover", this.mouseOverHandler , false);
+ Event.stopObserving(this.outerDiv,"mouseup", this.mouseUpHandler , false);
+ this.selectPluggedIn=false;
+},
+
+selectMouseUp: function(e) {
+ this.unplugSelect();
+ var cell=Event.element(e);
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ this.AdjustSelection(cell);
+},
+
+selectMouseOver: function(e) {
+ var cell=Event.element(e);
+ cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
+ if (!cell) return;
+ this.AdjustSelection(cell);
+ Event.stop(e);
+},
+
+getSelection: function() {
+ if (!this.SelectIdxStart || !this.SelectIdxEnd) return false;
+ var r1=Math.min(this.SelectIdxEnd.row,this.SelectIdxStart.row);
+ var r2=Math.max(this.SelectIdxEnd.row,this.SelectIdxStart.row);
+ var c1=Math.min(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ var c2=Math.max(this.SelectIdxEnd.column,this.SelectIdxStart.column);
+ return {r1:r1,c1:c1,r2:r2,c2:c2};
+},
+
+updateSelectOutline: function() {
+ var s=this.getSelection();
+ if (!s || s.r1 > s.r2) {
+ this.HideSelection();
+ return;
+ }
+ var top1=this.columns[s.c1].cell(s.r1).offsetTop;
+ var cell2=this.columns[s.c1].cell(s.r2);
+ var bottom2=cell2.offsetTop+cell2.offsetHeight;
+ var left1=this.columns[s.c1].dataCell.offsetLeft;
+ var left2=this.columns[s.c2].dataCell.offsetLeft;
+ var right2=left2+this.columns[s.c2].dataCell.offsetWidth;
+ //window.status='updateSelectOutline: '+s.r1+' '+s.r2+' top='+top1+' bot='+bottom2;
+ this.highlightDiv[0].style.top=this.highlightDiv[3].style.top=this.highlightDiv[1].style.top=(top1-3) + 'px';
+ this.highlightDiv[2].style.top=(bottom2-2)+'px';
+ this.highlightDiv[3].style.left=(left1-2)+'px';
+ this.highlightDiv[0].style.left=this.highlightDiv[2].style.left=(left1-1)+'px';
+ this.highlightDiv[1].style.left=(right2-1)+'px';
+ this.highlightDiv[0].style.width=this.highlightDiv[2].style.width=(right2-left1-1) + 'px';
+ this.highlightDiv[1].style.height=this.highlightDiv[3].style.height=(bottom2-top1) + 'px';
+ for (var i=0; i<4; i++)
+ this.highlightDiv[i].style.display='';
+},
+
+isSelected: function(r,c) {
+ var s=this.getSelection();
+ return s ? (s.r1 <= r) && (r <= s.r2) && (s.c1 <= c) && (c <= s.c2) : false;
+},
+
+HideSelection: function(cellList) {
+ for (var i=0; i<4; i++)
+ this.highlightDiv[i].style.display='none';
+},
+
+ShowSelection: function() {
+ this.updateSelectOutline();
+},
+
+/*
+ * @param what valid values are: null, 'all', 'formats', 'formulas', 'values'
+ */
+clearSelection: function() {
+ var s=this.getSelection();
+ if (!s) return;
+ var args=$A(arguments);
+ var what=args.shift();
+ if (typeof what=='object') what=args.shift(); // in case first arg is an event object
+ var v=(!what || what=='all') ? 1 : 0;
+ var whatobj={formats:v,formulas:v,values:v};
+ if (typeof what=='string') whatobj[what]=1;
+ if (whatobj.values) whatobj.formulas=1;
+ for (var r=s.r1; r<=s.r2; r++) {
+ for (var c=s.c1; c<=s.c2; c++) {
+ var gridcell=this.columns[c].cell(r);
+ if (whatobj.formats) {
+ gridcell.style.cssText='';
+ gridcell.RicoFormat={};
+ }
+ if (whatobj.formulas) gridcell.RicoFormula=null;
+ if (whatobj.values) gridcell.RicoValue=null;
+ this.formatCell(gridcell);
+ }
+ }
+},
+
+selectCellRC: function(r,c,adjFlag) {
+ if (r < 0 || r >= this.columns[0].numRows()) return;
+ this.HideSelection();
+ if (adjFlag) {
+ if (this.SelectIdxStart.tabIdx == this.columns[c].tabIdx)
+ this.SelectIdxEnd={row:r, column:c, tabIdx:this.columns[c].tabIdx};
+ } else {
+ this.SelectIdxStart=this.SelectIdxEnd={row:r, column:c, tabIdx:this.columns[c].tabIdx};
+ this.columns[c].cell(r).focus(); // causes IE to scroll cell into view (but not FF)
+ }
+ this.ShowSelection();
+},
+
+moveSelection: function(dr,dc,adjFlag,e) {
+ var selIdx=adjFlag ? this.SelectIdxEnd : this.SelectIdxStart;
+ var newr=selIdx.row+dr;
+ var newc=selIdx.column+dc;
+ if (newr>=0 && newr<this.columns[0].numRows() && newc>=1 && newc<this.columns.length)
+ this.selectCellRC(newr,newc,adjFlag);
+ if (e) Event.stop(e);
+},
+
+formatCell: function(cell) {
+ // TO DO: add currency/date formatting here
+ var v=cell.RicoValue;
+ if (v==null)
+ v='';
+ else if (typeof(v)=='number')
+ v = isNaN(v) ? '#VALUE' : cell.RicoFormat ? v.formatNumber(cell.RicoFormat) : v.toString();
+ else if (typeof v!='string')
+ v=v.toString();
+ v=v.replace(/^(\s*)/, '');
+ cell.style.paddingLeft=(RegExp.$1.length/2)+'em';
+ cell.innerHTML = v;
+},
+
+// action='add' or 'remove'
+updateDependencies: function(formulaCell,action) {
+ if (!formulaCell.RicoFormula) return;
+ //alert('updateDependencies '+action+': '+formulaCell.RicoRow+','+formulaCell.RicoCol);
+ var ranges=formulaCell.RicoFormula.getRanges();
+ for (var i=0; i<ranges.length; i++) {
+ if (!ranges[i]) continue;
+ var r1=Math.min(ranges[i][0],ranges[i][2]);
+ var r2=Math.max(ranges[i][0],ranges[i][2]);
+ var c1=Math.min(ranges[i][1],ranges[i][3]);
+ var c2=Math.max(ranges[i][1],ranges[i][3]);
+ for (var c=c1; c<=c2; c++) {
+ var col=this.columns[c];
+ for (var r=r1; r<=r2; r++) {
+ var cell=col.cell(r-1);
+ if (!cell.RicoDependencies) cell.RicoDependencies=new Rico.Formula.f_dependencies();
+ //alert('updateDependencies '+action+': '+formulaCell.RicoRow+','+formulaCell.RicoCol+' is dependent on '+cell.RicoRow+','+cell.RicoCol);
+ cell.RicoDependencies[action](formulaCell);
+ }
+ }
+ }
+},
+
+checkDependencies: function(cell) {
+ if (!cell.RicoDependencies) return;
+ var depcells=cell.RicoDependencies.items;
+ for (var i=0; i<depcells.length; i++) {
+ depcells[i].RicoValue=depcells[i].RicoFormula.eval();
+ this.formatCell(depcells[i]);
+ this.checkDependencies(depcells[i]);
+ }
+},
+
+showInputArea: function(clear,e) {
+ this.unplugScroll();
+ this.inputIdx=this.SelectIdxStart;
+ var col=this.columns[this.inputIdx.column];
+ this.inputIdx.cell=col.cell(this.inputIdx.row);
+ this.inputArea.style.top=(this.inputIdx.cell.offsetTop+col.dataCell.offsetTop)+'px';
+ this.inputArea.style.left=col.dataCell.offsetLeft+'px';
+ this.inputArea.style.display='';
+ this.inputArea.focus();
+ if (clear) {
+ if (Prototype.Browser.WebKit) {
+ // Safari does not bubble the event to the inputArea, so force it
+ this.inputArea.value=String.fromCharCode(e.charCode);
+ this.inputArea.setSelectionRange(1,1);
+ Event.stop(e);
+ } else this.inputArea.value='';
+ } else {
+ if (this.inputIdx.cell.RicoFormula)
+ this.inputArea.value=this.inputIdx.cell.RicoFormula.toEditString();
+ else
+ this.inputArea.value=this.inputIdx.cell.RicoValue || '';
+ }
+},
+
+closeInputArea: function(dr,dc,e) {
+ var newVal=this.inputArea.value;
+ var cell=this.inputIdx.cell;
+ if (this.options.checkEntry)
+ newVal=this.options.checkEntry(newVal,this.inputIdx.cell);
+ this.updateDependencies(cell,'remove');
+ cell.RicoFormula=null;
+ if (!this.options.noFormulas && newVal.charAt(0) == '=') {
+ // parse formula
+ cell.RicoFormula = new Rico.Formula(grid,cell);
+ cell.RicoFormula.parse(newVal);
+ cell.RicoValue = cell.RicoFormula.eval();
+ this.updateDependencies(cell,'add');
+ } else if (newVal=='') {
+ cell.RicoValue = null;
+ } else if (newVal.match(/^(true|false)$/i)) {
+ cell.RicoValue = eval(newVal.toLowerCase());
+ } else if (newVal.match(/^-?\d+(.\d*)?$/)) {
+ // parse number
+ cell.RicoValue = parseFloat(newVal);
+ } else {
+ cell.RicoValue=newVal;
+ }
+ this.formatCell(cell);
+ this.inputArea.blur();
+ this.inputArea.style.display='none';
+ this.checkDependencies(cell);
+ this.pluginScroll();
+ this.moveSelection(dr,dc,false,e);
+},
+
+inputKeydown: function(e) {
+ //window.status='inputKeydown keyCode='+e.keyCode;
+ switch (e.keyCode) {
+ case 13:
+ Event.stop(e);
+ this.closeInputArea(1,0,e);
+ return false;
+ case 9:
+ Event.stop(e);
+ this.closeInputArea(0,e.shiftKey ? -1 : 1,e);
+ return false;
+ case 27:
+ Event.stop(e);
+ this.inputArea.blur();
+ this.inputArea.style.display='none';
+ return false;
+ }
+ return true;
+},
+
+copyToClipbox: function() {
+ var s=this.getSelection();
+ if (!s) return;
+ var clipstr='';
+ for (var r=s.r1; r<=s.r2; r++) {
+ for (var c=s.c1; c<=s.c2; c++) {
+ if (c>s.c1) clipstr+="\t";
+ clipstr+=this.columns[c].cell(r).RicoValue;
+ }
+ clipstr+="\r\n";
+ }
+ this.clipBox.style.display='block';
+ this.clipBox.value=clipstr;
+ this.clipBox.select();
+},
+
+copySelection: function() {
+ var s=this.getSelection();
+ if (!s) return;
+ var clipArray=[];
+ for (var r=s.r1; r<=s.r2; r++) {
+ var cliprow=[];
+ for (var c=s.c1; c<=s.c2; c++) {
+ var clipcell={};
+ var gridcell=this.columns[c].cell(r);
+ clipcell.value=gridcell.RicoValue;
+ clipcell.style=gridcell.style.cssText;
+ if (gridcell.RicoFormat)
+ clipcell.format=Object.extend({}, gridcell.RicoFormat || {});
+ if (gridcell.RicoFormula)
+ clipcell.formula=Object.extend({}, gridcell.RicoFormula);
+ cliprow[c-s.c1]=clipcell;
+ }
+ clipArray[r-s.r1]=cliprow;
+ }
+ return clipArray;
+},
+
+pasteSelection: function(clipArray,pasteType) {
+ var s=this.getSelection();
+ if (!s || !clipArray) return;
+ pasteType=pasteType || 'all';
+ var clipclen=clipArray[0].length;
+ if (s.r1==s.r2 && s.c1==s.c2) {
+ s.r2=Math.min(s.r1+clipArray.length,this.columns[0].numRows())-1;
+ s.c2=Math.min(s.c1+clipclen,this.columns.length)-1;
+ }
+ for (var r=s.r1,clipr=0; r<=s.r2; r++) {
+ var arow=clipArray[clipr];
+ for (var c=s.c1,clipc=0; c<=s.c2; c++) {
+ var clipcell=arow[clipc];
+ var gridcell=this.columns[c].cell(r);
+ this.updateDependencies(gridcell,'remove');
+ gridcell.RicoFormula=null;
+ if (clipcell.formula) {
+ gridcell.RicoFormula=Object.extend({}, clipcell.formula);
+ gridcell.RicoFormula.cell=gridcell;
+ gridcell.RicoValue = gridcell.RicoFormula.eval();
+ this.updateDependencies(gridcell,'add');
+ } else {
+ gridcell.RicoValue=clipcell.value;
+ }
+ gridcell.style.cssText=clipcell.style;
+ if (clipcell.format)
+ gridcell.RicoFormat=Object.extend({}, clipcell.format);
+ this.formatCell(gridcell);
+ this.checkDependencies(gridcell);
+ clipc=(clipc+1) % clipclen;
+ }
+ clipr=(clipr+1) % clipArray.length;
+ }
+},
+
+formatSelection: function(newFormat) {
+ var s=this.getSelection();
+ if (!s) return;
+ for (var r=s.r1; r<=s.r2; r++) {
+ for (var c=s.c1; c<=s.c2; c++) {
+ var gridcell=this.cell(r,c);
+ gridcell.RicoFormat=newFormat;
+ this.formatCell(gridcell);
+ }
+ }
+},
+
+handleCtrlKey: function(e) {
+ switch (e.keyCode) {
+ // Ctrl-C
+ case 67:
+ this.clip=this.copySelection();
+ window.status='copy: '+this.clip.length;
+ Event.stop(e);
+ break;
+
+ // Ctrl-X
+ case 88:
+ this.clip=this.copySelection();
+ this.clearSelection();
+ Event.stop(e);
+ break;
+
+ // Ctrl-V
+ case 86:
+ window.status='paste: '+this.clip.length;
+ this.pasteSelection(this.clip);
+ Event.stop(e);
+ break;
+
+ // Ctrl-B
+ case 66:
+ this.toggleAttr('font-weight','normal','bold');
+ Event.stop(e);
+ break;
+
+ // Ctrl-I
+ case 73:
+ this.toggleAttr('font-style','normal','italic');
+ Event.stop(e);
+ break;
+ }
+},
+
+handleNormalKey: function(e) {
+ switch (e.keyCode) {
+ case 91:
+ case 16:
+ case 17:
+ case 18:
+ case 20:
+ case 27: return;
+
+ // tab
+ case 9: this.moveSelection(0,e.shiftKey ? -1 : 1,false,e); break;
+ // enter/return
+ case 13: this.moveSelection(1,0,false,e); break;
+ // arrow keys
+ case 37: this.moveSelection(0,-1,e.shiftKey,e); break;
+ case 38: this.moveSelection(-1,0,e.shiftKey,e); break;
+ case 39: this.moveSelection(0,1,e.shiftKey,e); break;
+ case 40: this.moveSelection(1,0,e.shiftKey,e); break;
+ // home
+ case 36: this.selectCellRC(this.SelectIdxStart.row,1); Event.stop(e); break;
+ // F2
+ case 113: this.showInputArea(false,e); break;
+
+ default: this.showInputArea(true,e); break;
+ }
+ return false;
+},
+
+gridKeydown: function(e) {
+ if (e.altKey) return;
+ var elem=Event.element(e);
+ if (elem.id=='inputArea') return true;
+ //window.status='gridKeydown keyCode='+e.keyCode;
+ if (e.ctrlKey)
+ this.handleCtrlKey(e);
+ else
+ this.handleNormalKey(e);
+},
+
+toggleAttr: function(attr,v1,v2) {
+ var v=this.getStyle(this.SelectIdxStart.row,this.SelectIdxStart.column,attr);
+ v=v==v2 ? v1 : v2;
+ this.updateSelectionStyle(attr,v);
+},
+
+getStyle: function(row,col,attr) {
+ var csstxt=this.columns[col].cell(row).style.cssText;
+ if (!csstxt) return;
+ if (csstxt.charAt(csstxt.length-1)!=';') csstxt+=';'; // opera
+ csstxt=' '+csstxt;
+ var re=new RegExp("[ ;]"+attr+"\\s*:\\s*([^ ;]*)\\s*;","i");
+ if (re.test(csstxt))
+ return RegExp.$1;
+ else
+ return;
+},
+
+updateStyleText: function(csstxt,attr,value) {
+ var newval=attr+':'+value+';';
+ if (!csstxt) return newval;
+ csstxt=' '+csstxt.strip();
+ if (csstxt.charAt(csstxt.length-1)!=';') csstxt+=';'; // opera
+ var re=new RegExp("([ ;])"+attr+"\\s*:\\s*([^ ;]*)\\s*;","i");
+ // safari must process the regexp twice, everyone else can run it once
+ if (re.test(csstxt))
+ return Prototype.Browser.WebKit ? csstxt.replace(re,"$1"+newval) : RegExp.leftContext+RegExp.$1+newval+RegExp.rightContext;
+ else
+ return csstxt+newval;
+},
+
+updateSelectionStyle: function(attr,newVal) {
+ var s=this.getSelection();
+ if (!s) return;
+ for (var c=s.c1; c<=s.c2; c++) {
+ var col=this.columns[c];
+ for (var r=s.r1; r<=s.r2; r++)
+ col.cell(r).style.cssText=this.updateStyleText(col.cell(r).style.cssText,attr,newVal);
+ }
+},
+
+showHelp: function() {
+ var msg="Rico Spreadsheet\n\n";
+ msg+="Ctrl-C = copy, Ctrl-X = cut, Ctrl-V = paste (only from/to cells on this grid)\n\n";
+ msg+="Formulas starting with '=' are supported\n";
+ msg+="Formulas may contain parentheses and the following operators: + - * / & % = > < <= >= <>\n";
+ msg+="'+' follows javascript rules regarding type conversion (which are slightly different from Excel)\n";
+ msg+="Formulas may refer to cells using 'A1' notation (and 'A1:B2' for ranges).\n";
+ msg+="The following functions are supported in formulas:\n\n";
+ var funclist=[];
+ for (var funcname in Rico.Formula.prototype)
+ if (funcname.substring(0,5)=='eval_') funclist.push(funcname.substring(5));
+ funclist.sort();
+ var funcstr=funclist.join(', ');
+ var i=funcstr.indexOf(' ',Math.floor(funcstr.length/2));
+ msg+=funcstr.substring(0,i)+"\n"+funcstr.substring(i+1);
+ msg+="\n\nFormula parsing based on code originally published by E. W. Bachtal at http://ewbi.blogs.com/develops/";
+ msg+="\nFuture functionality may include copy/paste from external applications, load/save, number & date formatting, and support for additional functions.";
+ alert(msg);
+}
+
+});
+
+
+Rico.Formula = Class.create();
+
+Rico.Formula.TOK_TYPE_NOOP = "noop";
+Rico.Formula.TOK_TYPE_OPERAND = "operand";
+Rico.Formula.TOK_TYPE_FUNCTION = "function";
+Rico.Formula.TOK_TYPE_SUBEXPR = "subexpression";
+Rico.Formula.TOK_TYPE_ARGUMENT = "argument";
+Rico.Formula.TOK_TYPE_OP_PRE = "operator-prefix";
+Rico.Formula.TOK_TYPE_OP_IN = "operator-infix";
+Rico.Formula.TOK_TYPE_OP_POST = "operator-postfix";
+Rico.Formula.TOK_TYPE_WSPACE = "white-space";
+Rico.Formula.TOK_TYPE_UNKNOWN = "unknown";
+
+Rico.Formula.TOK_SUBTYPE_START = "start";
+Rico.Formula.TOK_SUBTYPE_STOP = "stop";
+
+Rico.Formula.TOK_SUBTYPE_TEXT = "text";
+Rico.Formula.TOK_SUBTYPE_NUMBER = "number";
+Rico.Formula.TOK_SUBTYPE_LOGICAL = "logical";
+Rico.Formula.TOK_SUBTYPE_ERROR = "error";
+Rico.Formula.TOK_SUBTYPE_RANGE = "range";
+
+Rico.Formula.TOK_SUBTYPE_MATH = "math";
+Rico.Formula.TOK_SUBTYPE_CONCAT = "concatenate";
+Rico.Formula.TOK_SUBTYPE_INTERSECT = "intersect";
+Rico.Formula.TOK_SUBTYPE_UNION = "union";
+
+Rico.Formula.prototype = {
+
+initialize: function(grid,cell) {
+ this.grid=grid;
+ this.cell=cell;
+},
+
+// 'A' -> 1, 'AA' -> 27
+colLetter2Num: function(colstr) {
+ colstr=colstr.toUpperCase();
+ switch (colstr.length) {
+ case 1: return colstr.charCodeAt(0)-64;
+ case 2: return (colstr.charCodeAt(0)-64) * 26 + colstr.charCodeAt(1)-64;
+ default: return -1;
+ }
+},
+
+// 1 -> 'A', 27 -> 'AA'
+colNum2Letter: function(colnum) {
+ if (colnum <= 26) return String.fromCharCode(64+colnum);
+ colnum-=1;
+ return String.fromCharCode(64+Math.floor(colnum / 26),65+(colnum % 26));
+},
+
+
+toHTML: function() {
+ var indentCount = 0;
+
+ var indent = function() {
+ var s = "|";
+ for (var i = 0; i < indentCount; i++) {
+ s += " |";
+ }
+ return s;
+ };
+
+ var tokensHtml = "<table cellspacing='0'>";
+ tokensHtml += "<tr>";
+ tokensHtml += "<td class='token' style='font-weight: bold; width: 50px'>index</td>";
+ tokensHtml += "<td class='token' style='font-weight: bold; width: 125px'>type</td>";
+ tokensHtml += "<td class='token' style='font-weight: bold; width: 125px'>subtype</td>";
+ tokensHtml += "<td class='token' style='font-weight: bold; width: 150px'>token</td>";
+ tokensHtml += "<td class='token' style='font-weight: bold; width: 300px'>token tree</td></tr>";
+
+ this.tokens.reset();
+ while (this.tokens.moveNext()) {
+
+ var token = this.tokens.current();
+
+ if (token.subtype == Rico.Formula.TOK_SUBTYPE_STOP)
+ indentCount -= ((indentCount > 0) ? 1 : 0);
+
+ tokensHtml += "<tr>";
+
+ tokensHtml += "<td class='token'>" + (this.tokens.index + 1) + "</td>";
+ tokensHtml += "<td class='token'>" + token.type + "</td>";
+ tokensHtml += "<td class='token'>" + ((token.subtype.length == 0) ? " " : token.subtype) + "</td>";
+ tokensHtml += "<td class='token'>" + ((token.value.length == 0) ? " " : token.value).split(" ").join(" ") + "</td>";
+ tokensHtml += "<td class='token'>" + indent() + ((token.value.length == 0) ? " " : token.value).split(" ").join(" ") + "</td>";
+
+ tokensHtml += "</tr>";
+
+ if (token.subtype == Rico.Formula.TOK_SUBTYPE_START) indentCount++;
+ }
+ tokensHtml += "</table>";
+ return tokensHtml;
+},
+
+
+parseCellRef: function(refString) {
+ if (!refString) return null;
+ if (!refString.match(/^(\$?)([a-z]*)(\$?)(\d*)$/i)) return null;
+ var abscol=(RegExp.$1=='$');
+ var absrow=(RegExp.$3=='$');
+ var r=null,c=null;
+ if (RegExp.$2) {
+ c=this.colLetter2Num(RegExp.$2);
+ if (c<0 || c>=this.grid.columns.length) return null;
+ if (!abscol) c-=this.cell.RicoCol;
+ }
+ if (RegExp.$4) {
+ r=parseInt(RegExp.$4);
+ if (!absrow) r-=this.cell.RicoRow;
+ }
+ //alert('parseCellRef: '+refString+"\n"+'r='+r+' c='+c+' absrow='+absrow+' abscol='+abscol);
+ return {row:r, col:c, absRow:absrow, absCol:abscol};
+},
+
+
+resolveCellRef: function(cellRef) {
+ var r=cellRef.row;
+ var c=cellRef.col;
+ if (!cellRef.absRow) r+=this.cell.RicoRow;
+ if (!cellRef.absCol) c+=this.cell.RicoCol;
+ return {row:r, col:c};
+},
+
+
+resolveRange: function(token) {
+ if (!token.rangeStart) return null;
+ var a1=this.resolveCellRef(token.rangeStart);
+ var a2=this.resolveCellRef(token.rangeEnd);
+ //alert('resolveRange: '+a1.row+','+a1.col+' '+a2.row+','+a2.col);
+ var r1=Math.min(a1.row,a2.row);
+ var r2=Math.max(a1.row,a2.row);
+ var c1=Math.min(a1.col,a2.col) || 0;
+ var c2=Math.max(a1.col,a2.col) || this.grid.columns.length-1;
+ return [r1,c1,r2,c2];
+},
+
+
+range2evalstr: function(token) {
+ var rng=this.resolveRange(token);
+ return rng ? rng.join(',') : '';
+},
+
+
+cellref2str: function(cellRef) {
+ var ref=this.resolveCellRef(cellRef);
+ var c=this.colNum2Letter(ref.col);
+ if (cellRef.absCol) c='$'+c;
+ var r=ref.row.toString();
+ if (cellRef.absRow) r='$'+r;
+ return c+r;
+},
+
+
+range2str: function(token) {
+ var s1=this.cellref2str(token.rangeStart);
+ var s2=this.cellref2str(token.rangeEnd);
+ return (s1==s2) ? s1 : s1+':'+s2;
+},
+
+
+GetRange: function(r1,c1,r2,c2) {
+ if (typeof r1=='undefined' || typeof c1=='undefined') return NaN;
+ if (r1==r2 && c1==c2) return this.grid.columns[c1].cell(r1-1).RicoValue;
+ var result=[];
+ for (var r=r1; r<=r2; r++) {
+ var newRow=[];
+ for (var c=c1; c<=c2; c++)
+ newRow.push(this.grid.columns[c].cell(r-1).RicoValue);
+ result.push(newRow);
+ }
+ return result;
+},
+
+
+getRanges: function() {
+ var result=[];
+ this.tokens.reset();
+ while (this.tokens.moveNext()) {
+ var token = this.tokens.current();
+ if (token.subtype=='range') result.push(this.resolveRange(token));
+ }
+ return result;
+},
+
+
+eval_sum: function() {
+ var result=0;
+ for (var i=0; i<arguments.length; i++) {
+ arg=arguments[i];
+ if (arg==null) continue;
+ switch (typeof arg) {
+ case 'number':
+ result+=arg;
+ break;
+ case 'object':
+ for (var r=0; r<arg.length; r++)
+ for (var c=0; c<arg[r].length; c++)
+ if (typeof arg[r][c]=='number') result+=arg[r][c];
+ break;
+ }
+ }
+ return result;
+},
+
+
+eval_count: function() {
+ var result=0;
+ for (var i=0; i<arguments.length; i++) {
+ arg=arguments[i];
+ if (arg==null) continue;
+ switch (typeof arg) {
+ case 'object':
+ for (var r=0; r<arg.length; r++)
+ for (var c=0; c<arg[r].length; c++)
+ if (arg[r][c] || typeof arg[r][c]=='number') result++;
+ break;
+ default:
+ if (arg || typeof arg=='number') result++;
+ break;
+ }
+ }
+ return result;
+},
+
+
+eval_t: function(arg) {
+ return (typeof arg=='string') ? arg : '';
+},
+
+
+eval_trim: function(arg) {
+ arg=this.argString(arg);
+ return arg.strip();
+},
+
+
+eval_lower: function(arg) {
+ arg=this.argString(arg);
+ return arg.toLowerCase();
+},
+
+
+eval_upper: function(arg) {
+ arg=this.argString(arg);
+ return arg.toUpperCase();
+},
+
+
+eval_len: function(arg) {
+ arg=this.argString(arg);
+ return arg.length;
+},
+
+
+eval_value: function(arg) {
+ arg=this.argString(arg);
+ return parseFloat(arg);
+},
+
+
+eval_left: function(arg,numchars) {
+ arg=this.argString(arg);
+ if (typeof numchars!='number') numchars=1;
+ if (numchars<0) return NaN;
+ return arg.slice(0,numchars);
+},
+
+
+eval_right: function(arg,numchars) {
+ arg=this.argString(arg);
+ if (typeof numchars!='number') numchars=1;
+ if (numchars<0) return NaN;
+ if (numchars==0) return '';
+ return arg.slice(-numchars);
+},
+
+
+eval_mid: function(arg,start,numchars) {
+ arg=this.argString(arg);
+ if (typeof start!='number' || start<1) return NaN;
+ if (typeof numchars!='number' || numchars<0) return NaN;
+ return arg.substr(start-1,numchars);
+},
+
+
+eval_if: function(logical_test, value_true, value_false) {
+ var v=this.argBool(logical_test);
+ if (v==null) return NaN;
+ return v ? value_true : value_false;
+},
+
+
+eval_not: function(arg) {
+ var v=this.argBool(arg);
+ return (v==null) ? NaN : !v;
+},
+
+
+eval_and: function() {
+ var args = $A(arguments);
+ args.unshift(function(a,b) { return a&&b; });
+ return this.or_and.apply(this, args);
+},
+
+
+eval_or: function() {
+ var args = $A(arguments);
+ args.unshift(function(a,b) { return a||b; });
+ return this.or_and.apply(this, args);
+},
+
+
+or_and: function() {
+ var result;
+ var func=arguments[0];
+ for (var i=1; i<arguments.length; i++) {
+ arg=arguments[i];
+ if (arg==null) continue;
+ switch (typeof arg) {
+ case 'object':
+ for (var r=0; r<arg.length; r++)
+ for (var c=0; c<arg[r].length; c++) {
+ var v=this.argBool(arg[r][c])
+ if (v!=null) result=(typeof result=='undefined') ? v : func(result,v);
+ }
+ break;
+ default:
+ var v=this.argBool(arg)
+ if (v!=null) result=(typeof result=='undefined') ? v : func(result,v);
+ break;
+ }
+ }
+ return (typeof result=='undefined') ? NaN : result;
+},
+
+
+eval_abs: function(arg) { return Math.abs(this.argNumber(arg)); },
+eval_acos: function(arg) { return Math.acos(this.argNumber(arg)); },
+eval_asin: function(arg) { return Math.asin(this.argNumber(arg)); },
+eval_atan: function(arg) { return Math.atan(this.argNumber(arg)); },
+eval_atan2: function(argx,argy) { return Math.atan2(this.argNumber(argy),this.argNumber(argx)); },
+eval_ceiling: function(arg) { return Math.ceil(this.argNumber(arg)); },
+eval_cos: function(arg) { return Math.cos(this.argNumber(arg)); },
+eval_exp: function(arg) { return Math.exp(this.argNumber(arg)); },
+eval_floor: function(arg) { return Math.floor(this.argNumber(arg)); },
+eval_ln: function(arg) { return Math.log(this.argNumber(arg)); },
+eval_mod: function(num,divisor) { return this.argNumber(num) % this.argNumber(divisor); },
+eval_pi: function() { return Math.PI; },
+eval_power: function(argx,argy) { return Math.pow(this.argNumber(argx),this.argNumber(argy)); },
+eval_rand: function() { return Math.random(); },
+eval_round: function(arg) { return Math.round(this.argNumber(arg)); },
+eval_sin: function(arg) { return Math.sin(this.argNumber(arg)); },
+eval_sqrt: function(arg) { return Math.sqrt(this.argNumber(arg)); },
+eval_tan: function(arg) { return Math.tan(this.argNumber(arg)); },
+
+
+argNumber: function(arg) {
+ switch (typeof arg) {
+ case 'boolean': return arg;
+ case 'number': return arg;
+ case 'string': return parseFloat(arg);
+ default: return null;
+ }
+},
+
+
+argBool: function(arg) {
+ switch (typeof arg) {
+ case 'boolean': return arg;
+ case 'number': return arg!=0;
+ default: return null;
+ }
+},
+
+
+argString: function(arg) {
+ switch (typeof arg) {
+ case 'string': return arg;
+ case 'boolean':
+ case 'number': return arg.toString();
+ default: return '';
+ }
+},
+
+
+eval: function() {
+ var evalstr='';
+ this.tokens.reset();
+ while (this.tokens.moveNext()) {
+ var token = this.tokens.current();
+ switch (token.type) {
+ case 'function':
+ if (token.subtype=='start') {
+ var funcname='eval_'+token.value.toLowerCase();
+ if (typeof this[funcname]!='function') {
+ alert('Unknown function: '+token.value);
+ return '#ERROR';
+ }
+ evalstr+='this.'+funcname+'(';
+ } else
+ evalstr+=')';
+ break;
+ case 'subexpression':
+ if (token.subtype=='start')
+ evalstr+='(';
+ else
+ evalstr+=')';
+ break;
+ case 'operator-infix':
+ if (token.value=='&')
+ evalstr+='+';
+ else if (token.value=='=')
+ evalstr+='==';
+ else if (token.value=='<>')
+ evalstr+='!=';
+ else
+ evalstr+=token.value;
+ break;
+ case 'operator-postfix':
+ if (token.value=='%')
+ evalstr+='/100';
+ else
+ evalstr+=token.value;
+ break;
+ case 'operand':
+ if (token.subtype=='range')
+ evalstr+='this.GetRange('+this.range2evalstr(token)+')';
+ else if (token.subtype=='text')
+ evalstr+='"'+token.value+'"';
+ else
+ evalstr+=token.value;
+ break;
+ default:
+ evalstr+=token.value;
+ break;
+ }
+ }
+ this.lastEval=evalstr;
+ //window.status=evalstr;
+ try {
+ var result=eval(evalstr)
+ return result;
+ } catch(e) { alert(e.message); return '#ERROR'; }
+},
+
+
+toEditString: function() {
+ var s='=';
+ this.tokens.reset();
+ while (this.tokens.moveNext()) {
+ var token = this.tokens.current();
+ switch (token.type) {
+ case 'function':
+ if (token.subtype=='start')
+ s+=token.value+'(';
+ else
+ s+=')';
+ break;
+ case 'subexpression':
+ if (token.subtype=='start')
+ s+='(';
+ else
+ s+=')';
+ break;
+ case 'operand':
+ if (token.subtype=='range')
+ s+=this.range2str(token);
+ else if (token.subtype=='text')
+ s+='"'+token.value+'"';
+ else
+ s+=token.value;
+ break;
+ default:
+ s+=token.value;
+ }
+ }
+ return s;
+},
+
+
+// Excel formula parser
+// from http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html
+parse: function(formula) {
+ var tokens = new Rico.Formula.f_tokens();
+ var tokenStack = new Rico.Formula.f_tokenStack();
+
+ var offset = 0;
+
+ var currentChar = function() { return formula.substr(offset, 1); };
+ var doubleChar = function() { return formula.substr(offset, 2); };
+ var nextChar = function() { return formula.substr(offset + 1, 1); };
+ var EOF = function() { return (offset >= formula.length); };
+
+ var token = "";
+
+ var inString = false;
+ var inPath = false;
+ var inRange = false;
+ var inError = false;
+
+ while (formula.length > 0) {
+ if (formula.substr(0, 1) == " ")
+ formula = formula.substr(1);
+ else {
+ if (formula.substr(0, 1) == "=")
+ formula = formula.substr(1);
+ break;
+ }
+ }
+
+ while (!EOF()) {
+
+ // state-dependent character evaluation (order is important)
+
+ // double-quoted strings
+ // embeds are doubled
+ // end marks token
+
+ if (inString) {
+ if (currentChar() == "\"") {
+ if (nextChar() == "\"") {
+ token += "\"";
+ offset += 1;
+ } else {
+ inString = false;
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND, Rico.Formula.TOK_SUBTYPE_TEXT);
+ token = "";
+ }
+ } else {
+ token += currentChar();
+ }
+ offset += 1;
+ continue;
+ }
+
+ // single-quoted strings (links)
+ // embeds are double
+ // end does not mark a token
+
+ if (inPath) {
+ if (currentChar() == "'") {
+ if (nextChar() == "'") {
+ token += "'";
+ offset += 1;
+ } else {
+ inPath = false;
+ }
+ } else {
+ token += currentChar();
+ }
+ offset += 1;
+ continue;
+ }
+
+ // bracked strings (range offset or linked workbook name)
+ // no embeds (changed to "()" by Excel)
+ // end does not mark a token
+
+ if (inRange) {
+ if (currentChar() == "]") {
+ inRange = false;
+ }
+ token += currentChar();
+ offset += 1;
+ continue;
+ }
+
+ // error values
+ // end marks a token, determined from absolute list of values
+
+ if (inError) {
+ token += currentChar();
+ offset += 1;
+ if ((",#NULL!,#DIV/0!,#VALUE!,#REF!,#NAME?,#NUM!,#N/A,").indexOf("," + token + ",") != -1) {
+ inError = false;
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND, Rico.Formula.TOK_SUBTYPE_ERROR);
+ token = "";
+ }
+ continue;
+ }
+
+ // independent character evaulation (order not important)
+
+ // establish state-dependent character evaluations
+
+ if (currentChar() == "\"") {
+ if (token.length > 0) {
+ // not expected
+ tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN);
+ token = "";
+ }
+ inString = true;
+ offset += 1;
+ continue;
+ }
+
+ if (currentChar() == "'") {
+ if (token.length > 0) {
+ // not expected
+ tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN);
+ token = "";
+ }
+ inPath = true;
+ offset += 1;
+ continue;
+ }
+
+ if (currentChar() == "[") {
+ inRange = true;
+ token += currentChar();
+ offset += 1;
+ continue;
+ }
+
+ if (currentChar() == "#") {
+ if (token.length > 0) {
+ // not expected
+ tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN);
+ token = "";
+ }
+ inError = true;
+ token += currentChar();
+ offset += 1;
+ continue;
+ }
+
+ // mark start and end of arrays and array rows
+
+ if (currentChar() == "{") {
+ if (token.length > 0) {
+ // not expected
+ tokens.add(token, Rico.Formula.TOK_TYPE_UNKNOWN);
+ token = "";
+ }
+ tokenStack.push(tokens.add("ARRAY", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START));
+ tokenStack.push(tokens.add("ARRAYROW", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START));
+ offset += 1;
+ continue;
+ }
+
+ if (currentChar() == ";") {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.addRef(tokenStack.pop());
+ tokens.add(",", Rico.Formula.TOK_TYPE_ARGUMENT);
+ tokenStack.push(tokens.add("ARRAYROW", Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START));
+ offset += 1;
+ continue;
+ }
+
+ if (currentChar() == "}") {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.addRef(tokenStack.pop());
+ tokens.addRef(tokenStack.pop());
+ offset += 1;
+ continue;
+ }
+
+ // trim white-space
+
+ if (currentChar() == " ") {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.add("", Rico.Formula.TOK_TYPE_WSPACE);
+ offset += 1;
+ while ((currentChar() == " ") && (!EOF())) {
+ offset += 1;
+ }
+ continue;
+ }
+
+ // multi-character comparators
+
+ if ((",>=,<=,<>,").indexOf("," + doubleChar() + ",") != -1) {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.add(doubleChar(), Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_LOGICAL);
+ offset += 2;
+ continue;
+ }
+
+ // standard infix operators
+
+ if (("+-*/^&=><").indexOf(currentChar()) != -1) {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_IN);
+ offset += 1;
+ continue;
+ }
+
+ // standard postfix operators
+
+ if (("%").indexOf(currentChar()) != -1) {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_POST);
+ offset += 1;
+ continue;
+ }
+
+ // start subexpression or function
+
+ if (currentChar() == "(") {
+ if (token.length > 0) {
+ tokenStack.push(tokens.add(token, Rico.Formula.TOK_TYPE_FUNCTION, Rico.Formula.TOK_SUBTYPE_START));
+ token = "";
+ } else {
+ tokenStack.push(tokens.add("", Rico.Formula.TOK_TYPE_SUBEXPR, Rico.Formula.TOK_SUBTYPE_START));
+ }
+ offset += 1;
+ continue;
+ }
+
+ // function, subexpression, array parameters
+
+ if (currentChar() == ",") {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ if (!(tokenStack.type() == Rico.Formula.TOK_TYPE_FUNCTION)) {
+ tokens.add(currentChar(), Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_UNION);
+ } else {
+ tokens.add(currentChar(), Rico.Formula.TOK_TYPE_ARGUMENT);
+ }
+ offset += 1;
+ continue;
+ }
+
+ // stop subexpression
+
+ if (currentChar() == ")") {
+ if (token.length > 0) {
+ tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+ token = "";
+ }
+ tokens.addRef(tokenStack.pop());
+ offset += 1;
+ continue;
+ }
+
+ // token accumulation
+
+ token += currentChar();
+ offset += 1;
+
+ }
+
+ // dump remaining accumulation
+
+ if (token.length > 0) tokens.add(token, Rico.Formula.TOK_TYPE_OPERAND);
+
+ // move all tokens to a new collection, excluding all unnecessary white-space tokens
+
+ var tokens2 = new Rico.Formula.f_tokens();
+
+ while (tokens.moveNext()) {
+
+ token = tokens.current();
+
+ if (token.type == Rico.Formula.TOK_TYPE_WSPACE) {
+ if ((tokens.BOF()) || (tokens.EOF())) {}
+ else if (!(
+ ((tokens.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) ||
+ ((tokens.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) ||
+ (tokens.previous().type == Rico.Formula.TOK_TYPE_OPERAND)
+ )
+ ) {}
+ else if (!(
+ ((tokens.next().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens.next().subtype == Rico.Formula.TOK_SUBTYPE_START)) ||
+ ((tokens.next().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens.next().subtype == Rico.Formula.TOK_SUBTYPE_START)) ||
+ (tokens.next().type == Rico.Formula.TOK_TYPE_OPERAND)
+ )
+ ) {}
+ else
+ tokens2.add(token.value, Rico.Formula.TOK_TYPE_OP_IN, Rico.Formula.TOK_SUBTYPE_INTERSECT);
+ continue;
+ }
+
+ tokens2.addRef(token);
+
+ }
+
+ // switch infix "-" operator to prefix when appropriate, switch infix "+" operator to noop when appropriate, identify operand
+ // and infix-operator subtypes, pull "@" from in front of function names
+
+ while (tokens2.moveNext()) {
+
+ token = tokens2.current();
+
+ if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.value == "-")) {
+ if (tokens2.BOF())
+ token.type = Rico.Formula.TOK_TYPE_OP_PRE;
+ else if (
+ ((tokens2.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) ||
+ ((tokens2.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) ||
+ (tokens2.previous().type == Rico.Formula.TOK_TYPE_OP_POST) ||
+ (tokens2.previous().type == Rico.Formula.TOK_TYPE_OPERAND)
+ )
+ token.subtype = Rico.Formula.TOK_SUBTYPE_MATH;
+ else
+ token.type = Rico.Formula.TOK_TYPE_OP_PRE;
+ continue;
+ }
+
+ if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.value == "+")) {
+ if (tokens2.BOF())
+ token.type = Rico.Formula.TOK_TYPE_NOOP;
+ else if (
+ ((tokens2.previous().type == Rico.Formula.TOK_TYPE_FUNCTION) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) ||
+ ((tokens2.previous().type == Rico.Formula.TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype == Rico.Formula.TOK_SUBTYPE_STOP)) ||
+ (tokens2.previous().type == Rico.Formula.TOK_TYPE_OP_POST) ||
+ (tokens2.previous().type == Rico.Formula.TOK_TYPE_OPERAND)
+ )
+ token.subtype = Rico.Formula.TOK_SUBTYPE_MATH;
+ else
+ token.type = Rico.Formula.TOK_TYPE_NOOP;
+ continue;
+ }
+
+ if ((token.type == Rico.Formula.TOK_TYPE_OP_IN) && (token.subtype.length == 0)) {
+ if (("<>=").indexOf(token.value.substr(0, 1)) != -1)
+ token.subtype = Rico.Formula.TOK_SUBTYPE_LOGICAL;
+ else if (token.value == "&")
+ token.subtype = Rico.Formula.TOK_SUBTYPE_CONCAT;
+ else
+ token.subtype = Rico.Formula.TOK_SUBTYPE_MATH;
+ continue;
+ }
+
+ if ((token.type == Rico.Formula.TOK_TYPE_OPERAND) && (token.subtype.length == 0)) {
+ if (isNaN(parseFloat(token.value)))
+ if ((token.value == 'TRUE') || (token.value == 'FALSE'))
+ token.subtype = Rico.Formula.TOK_SUBTYPE_LOGICAL;
+ else {
+ token.subtype = Rico.Formula.TOK_SUBTYPE_RANGE;
+ var a=token.value.split(':');
+ token.rangeStart=this.parseCellRef(a[0]);
+ token.rangeEnd=a.length>1 ? this.parseCellRef(a[1]) : token.rangeStart;
+ }
+ else
+ token.subtype = Rico.Formula.TOK_SUBTYPE_NUMBER;
+ continue;
+ }
+
+ if (token.type == Rico.Formula.TOK_TYPE_FUNCTION) {
+ if (token.value.substr(0, 1) == "@")
+ token.value = token.value.substr(1);
+ continue;
+ }
+
+ }
+
+ tokens2.reset();
+
+ // move all tokens to a new collection, excluding all noops
+
+ this.tokens = new Rico.Formula.f_tokens();
+
+ while (tokens2.moveNext()) {
+ if (tokens2.current().type != Rico.Formula.TOK_TYPE_NOOP)
+ this.tokens.addRef(tokens2.current());
+ }
+}
+
+}
+
+
+Rico.Formula.f_token = Class.create();
+Rico.Formula.f_token.prototype = {
+ initialize: function(value, type, subtype) {
+ this.value = value;
+ this.type = type;
+ this.subtype = subtype;
+ }
+}
+
+
+Rico.Formula.f_tokens = Class.create();
+Rico.Formula.f_tokens.prototype = {
+ initialize: function() {
+ this.items = new Array();
+ this.index = -1;
+ },
+
+ addRef: function(token) {
+ this.items.push(token);
+ },
+
+ add: function(value, type, subtype) {
+ if (!subtype) subtype = "";
+ var token = new Rico.Formula.f_token(value, type, subtype);
+ this.addRef(token);
+ return token;
+ },
+
+ reset: function() {
+ this.index = -1;
+ },
+
+ BOF: function() {
+ return (this.index <= 0);
+ },
+
+ EOF: function() {
+ return (this.index >= (this.items.length - 1));
+ },
+
+ moveNext: function() {
+ if (this.EOF()) return false; this.index++; return true;
+ },
+
+ current: function() {
+ if (this.index == -1) return null; return (this.items[this.index]);
+ },
+
+ next: function() {
+ if (this.EOF()) return null; return (this.items[this.index + 1]);
+ },
+
+ previous: function() {
+ if (this.index < 1) return null; return (this.items[this.index - 1]);
+ }
+}
+
+
+Rico.Formula.f_tokenStack = Class.create();
+Rico.Formula.f_tokenStack.prototype = {
+ initialize: function() {
+ this.items = new Array();
+ },
+
+ push: function(token) {
+ this.items.push(token);
+ },
+
+ pop: function() {
+ var token = this.items.pop();
+ return (new Rico.Formula.f_token("", token.type, Rico.Formula.TOK_SUBTYPE_STOP));
+ },
+
+ token: function() {
+ return ((this.items.length > 0) ? this.items[this.items.length - 1] : null);
+ },
+
+ value: function() {
+ return ((this.token()) ? this.token().value : "");
+ },
+
+ type: function() {
+ return ((this.token()) ? this.token().type : "");
+ },
+
+ subtype: function() {
+ return ((this.token()) ? this.token().subtype : "");
+ }
+}
+
+
+Rico.Formula.f_dependencies = Class.create();
+Rico.Formula.f_dependencies.prototype = {
+ initialize: function() {
+ this.items = [];
+ },
+
+ add: function(cell) {
+ if (!this.items.include(cell)) this.items.push(cell);
+ },
+
+ remove: function(cell) {
+ this.items=this.items.select(function(item) { return (item != cell); });
+ },
+
+ find: function(cell) {
+ return this.items.detect(function(item) { return (item==cell); });
+ },
+
+ clear: function() {
+ this.items.clear();
+ }
+}
+
+
+Object.extend(Rico.Menu.prototype, {
+
+showSheetMenu: function(e,hideFunc) {
+ var elem=this.showSimpleMenu(e,hideFunc);
+ if (!this.grid) return;
+ var newIdx=this.grid.cellIndex(elem);
+ if (!this.grid.isSelected(newIdx.row,newIdx.column))
+ this.grid.selectCellRC(newIdx.row,newIdx.column,false);
+}
+
+});
+
+
+Rico.includeLoaded('ricoSheet.js');
--- /dev/null
+/**
+ * (c) 2005-2007 Richard Cowin (http://openrico.org)
+ * (c) 2005-2007 Matt Brown (http://dowdybrown.com)
+ *
+ * Rico is 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
+ **/
+
+
+if(typeof Rico=='undefined') throw("SimpleGrid requires the Rico JavaScript framework");
+if(typeof RicoUtil=='undefined') throw("SimpleGrid requires the RicoUtil Library");
+if(typeof RicoTranslate=='undefined') throw("SimpleGrid requires the RicoTranslate Library");
+
+Rico.SimpleGrid = Class.create();
+
+Rico.SimpleGrid.prototype = {
+
+ initialize: function( tableId, options ) {
+ Object.extend(this, new Rico.GridCommon);
+ this.baseInit(tableId);
+ Rico.setDebugArea(tableId+"_debugmsgs"); // if used, this should be a textarea
+ Object.extend(this.options, options || {});
+ this.tableId = tableId;
+ this.createDivs();
+ this.hdrTabs=new Array(2);
+ for (var i=0; i<2; i++) {
+ this.tabs[i]=$(tableId+'_tab'+i);
+ this.hdrTabs[i]=$(tableId+'_tab'+i+'h');
+ if (i==0) this.tabs[i].style.position='absolute';
+ if (i==0) this.tabs[i].style.left='0px';
+ this.hdrTabs[i].style.position='absolute';
+ this.hdrTabs[i].style.top='0px';
+ this.hdrTabs[i].style.zIndex=1;
+ this.thead[i]=this.hdrTabs[i];
+ this.tbody[i]=this.tabs[i];
+ this.headerColCnt = this.getColumnInfo(this.hdrTabs[i].rows);
+ if (i==0) this.options.frozenColumns=this.headerColCnt;
+ }
+ if (this.headerColCnt==0) {
+ alert('ERROR: no columns found in "'+this.tableId+'"');
+ return;
+ }
+ this.hdrHt=Math.max(RicoUtil.nan2zero(this.hdrTabs[0].offsetHeight),this.hdrTabs[1].offsetHeight);
+ for (var i=0; i<2; i++)
+ if (i==0) this.tabs[i].style.top=this.hdrHt+'px';
+ this.createColumnArray();
+ this.pageSize=this.columns[0].dataColDiv.childNodes.length;
+ this.sizeDivs();
+ this.attachMenuEvents();
+ this.scrollEventFunc=this.handleScroll.bindAsEventListener(this);
+ this.pluginScroll();
+ if (this.options.windowResize)
+ Event.observe(window,"resize", this.sizeDivs.bindAsEventListener(this), false);
+ },
+
+ /**
+ * Register a menu that will only be used in the scrolling part of the grid.
+ * If submenus are used, they must be registered after the main menu.
+ */
+ registerScrollMenu: function(menu) {
+ if (!this.menu) this.menu=menu;
+ menu.grid=this;
+ menu.showmenu=menu.showSimpleMenu;
+ menu.showSubMenu=menu.showSimpleSubMenu;
+ menu.createDiv(this.scrollDiv);
+ },
+
+ handleMenuClick: function(e) {
+ this.cancelMenu();
+ this.menuCell=RicoUtil.getParentByTagName(Event.element(e),'div');
+ this.highlightEnabled=false;
+ if (this.hideScroll) this.scrollDiv.style.overflow="hidden";
+ if (this.menu.buildGridMenu) this.menu.buildGridMenu(this.menuCell);
+ this.menu.showmenu(e,this.closeMenu.bind(this));
+ },
+
+ closeMenu: function() {
+ if (this.hideScroll) this.scrollDiv.style.overflow="";
+ this.highlightEnabled=true;
+ },
+
+ sizeDivs: function() {
+ if (this.outerDiv.offsetParent.style.display=='none') return;
+ this.baseSizeDivs();
+ var maxHt=Math.max(this.options.maxHt || this.availHt(), 50);
+ var totHt=Math.min(this.hdrHt+this.dataHt, maxHt);
+ Rico.writeDebugMsg('sizeDivs '+this.tableId+': hdrHt='+this.hdrHt+' dataHt='+this.dataHt);
+ this.dataHt=totHt-this.hdrHt;
+ if (this.scrWi>0) this.dataHt+=this.options.scrollBarWidth;
+ this.scrollDiv.style.height=this.dataHt+'px';
+ var divAdjust=2;
+ this.innerDiv.style.width=(this.scrWi-this.options.scrollBarWidth+divAdjust)+'px';
+ this.innerDiv.style.height=this.hdrHt+'px';
+ totHt+=divAdjust;
+ this.resizeDiv.style.height=this.frozenTabs.style.height=totHt+'px';
+ this.outerDiv.style.height=(totHt+this.options.scrollBarWidth)+'px';
+ this.setHorizontalScroll();
+ }
+
+};
+
+if (Rico.Menu) {
+Object.extend(Rico.Menu.prototype, {
+
+showSimpleMenu: function(e,hideFunc) {
+ Event.stop(e);
+ this.hideFunc=hideFunc;
+ if (this.div.childNodes.length==0) {
+ this.cancelmenu();
+ return false;
+ }
+ this.clientX=Event.pointerX(e);
+ this.clientY=Event.pointerY(e);
+ var elem=Event.element(e);
+ while (elem && !Element.hasClassName(elem,'ricoLG_cell'))
+ elem=elem.parentNode;
+ if (!elem) return false;
+ var td=RicoUtil.getParentByTagName(elem,'td');
+
+ var newLeft=Math.floor(td.offsetLeft+td.offsetWidth/2);
+ if (this.direction == 'rtl') {
+ if (newLeft > this.width) newLeft-=this.width;
+ } else {
+ if (newLeft+this.width+this.options.margin > this.grid.scrollDiv.scrollLeft+this.grid.scrollDiv.clientWidth) newLeft-=this.width;
+ }
+ this.div.style.visibility="hidden";
+ this.div.style.display="block";
+ var contentHt=this.div.offsetHeight;
+ var newTop=Math.floor(elem.offsetTop+elem.offsetHeight/2);
+ if (newTop+contentHt+this.options.margin > this.grid.scrollDiv.scrollTop+this.grid.scrollDiv.clientHeight)
+ newTop=Math.max(newTop-contentHt,0);
+ this.openPopup(newLeft,newTop);
+ this.div.style.visibility ="visible";
+ return elem;
+},
+
+showSimpleSubMenu: function(a,submenu) {
+ if (this.openSubMenu) this.hideSubMenu();
+ this.openSubMenu=submenu;
+ this.openMenuAnchor=a;
+ if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen';
+ var top=parseInt(this.div.style.top);
+ var left=parseInt(this.div.style.left);
+ submenu.openPopup(left+a.offsetWidth,top+a.offsetTop);
+ submenu.div.style.visibility ="visible";
+}
+
+});
+}
+
+Object.extend(Rico.TableColumn.prototype, {
+
+initialize: function(grid,colIdx,hdrInfo,tabIdx) {
+ this.baseInit(grid,colIdx,hdrInfo,tabIdx);
+}
+
+});
+
+Rico.includeLoaded('ricoSimpleGrid.js');
--- /dev/null
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
+ xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes"
+exclude-result-prefixes="xhtml xsl fn xs xdt">
+
+<xsl:output
+omit-xml-declaration="yes"
+method="html"
+doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
+doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
+
+<xsl:attribute-set name="ricoTable">
+ <xsl:attribute name="cellspacing">0</xsl:attribute>
+ <xsl:attribute name="cellpadding">0</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- the identity template -->
+
+<xsl:template match="*">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+
+<!-- Transform head section -->
+
+<xsl:template match="xhtml:head">
+ <xsl:copy>
+ <xsl:apply-templates mode="head"/>
+<script type="text/javascript">
+//<![CDATA[
+if (typeof ricoInit!='undefined') {
+ if (window.addEventListener)
+ window.addEventListener('load', ricoInit, false);
+ else if (window.attachEvent)
+ window.attachEvent('onload', ricoInit);
+}
+// ]]>
+</script>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="*[name()!='script']" mode="head">
+ <xsl:copy>
+ <xsl:copy-of select="@*|node()"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="xhtml:script" mode="head">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:value-of select="." disable-output-escaping="yes"/>
+ </xsl:copy>
+</xsl:template>
+
+
+<!-- Transform tables with class ricoSimpleGrid -->
+
+<xsl:template match="xhtml:table[@class='ricoSimpleGrid']">
+<xsl:choose>
+
+<xsl:when test="xhtml:thead">
+<xsl:call-template name="processTable">
+<xsl:with-param name="id" select="@id"/>
+<xsl:with-param name="headRows" select="xhtml:thead/xhtml:tr"/>
+<xsl:with-param name="bodyRows" select="xhtml:tbody/xhtml:tr"/>
+</xsl:call-template>
+</xsl:when>
+
+<xsl:when test="xhtml:tbody">
+<xsl:call-template name="processTable">
+<xsl:with-param name="id" select="@id"/>
+<xsl:with-param name="headRows" select="xhtml:tbody/xhtml:tr[1]"/>
+<xsl:with-param name="bodyRows" select="xhtml:tbody/xhtml:tr[position() > 1]"/>
+</xsl:call-template>
+</xsl:when>
+
+<xsl:otherwise>
+<xsl:call-template name="processTable">
+<xsl:with-param name="id" select="@id"/>
+<xsl:with-param name="headRows" select="xhtml:tr[1]"/>
+<xsl:with-param name="bodyRows" select="xhtml:tr[position() > 1]"/>
+</xsl:call-template>
+</xsl:otherwise>
+
+</xsl:choose>
+</xsl:template>
+
+
+<!-- Perform the actual table transformation -->
+
+<xsl:template name="processTable">
+<xsl:param name="id" />
+<xsl:param name="headRows" />
+<xsl:param name="bodyRows" />
+
+<xsl:variable name="headIdx">
+<xsl:choose>
+<xsl:when test="$headRows[@class='ricoHeading']">
+<xsl:value-of select="count($headRows[@class='ricoHeading']/preceding-sibling::*)+1"/>
+</xsl:when>
+<xsl:otherwise>
+<xsl:value-of select="count($headRows)"/>
+</xsl:otherwise>
+</xsl:choose>
+</xsl:variable>
+
+<xsl:variable name="headMain" select="$headRows[position()=$headIdx]"/>
+<xsl:variable name="headCols" select="$headMain/xhtml:th | $headMain/xhtml:td"/>
+
+<!--
+<p><xsl:value-of select="$id"/>
+<br />headRowCnt: <xsl:value-of select="count($headRows)"/>
+<br />headIdx: <xsl:value-of select="$headIdx"/>
+<br />bodyRowCnt: <xsl:value-of select="count($bodyRows)"/>
+</p>
+-->
+
+<xsl:element name="div">
+<xsl:attribute name="id"><xsl:value-of select="concat($id,'_outerDiv')"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_outerDiv</xsl:attribute>
+<xsl:attribute name="onload"></xsl:attribute>
+
+<!-- Create frozen (left) pane -->
+
+<xsl:element name="div">
+<xsl:attribute name="id"><xsl:value-of select="concat($id,'_frozenTabsDiv')"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_frozenTabsDiv</xsl:attribute>
+
+<xsl:call-template name="convertTHead">
+<xsl:with-param name="rows" select="$headRows"/>
+<xsl:with-param name="headIdx" select="$headIdx"/>
+<xsl:with-param name="frozen" select="1"/>
+<xsl:with-param name="id" select="concat($id,'_tab0h')"/>
+</xsl:call-template>
+
+<xsl:call-template name="convertTBody">
+<xsl:with-param name="rows" select="$bodyRows"/>
+<xsl:with-param name="cols" select="$headCols"/>
+<xsl:with-param name="id" select="concat($id,'_tab0')"/>
+<xsl:with-param name="frozen" select="1"/>
+</xsl:call-template>
+
+</xsl:element>
+
+<xsl:element name="div">
+<xsl:attribute name="id"><xsl:value-of select="concat($id,'_innerDiv')"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_innerDiv</xsl:attribute>
+
+<xsl:element name="div">
+<xsl:attribute name="id"><xsl:value-of select="concat($id,'_scrollTabsDiv')"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_scrollTabsDiv</xsl:attribute>
+
+<xsl:call-template name="convertTHead">
+<xsl:with-param name="rows" select="$headRows"/>
+<xsl:with-param name="headIdx" select="$headIdx"/>
+<xsl:with-param name="frozen" select="0"/>
+<xsl:with-param name="id" select="concat($id,'_tab1h')"/>
+</xsl:call-template>
+
+</xsl:element>
+</xsl:element>
+
+<xsl:element name="div">
+<xsl:attribute name="id"><xsl:value-of select="concat($id,'_scrollDiv')"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_scrollDiv</xsl:attribute>
+
+<xsl:call-template name="convertTBody">
+<xsl:with-param name="rows" select="$bodyRows"/>
+<xsl:with-param name="cols" select="$headCols"/>
+<xsl:with-param name="id" select="concat($id,'_tab1')"/>
+<xsl:with-param name="frozen" select="0"/>
+</xsl:call-template>
+</xsl:element>
+
+</xsl:element>
+
+</xsl:template>
+
+
+<!-- Convert thead section -->
+
+<xsl:template name="convertTHead">
+<xsl:param name = "rows" />
+<xsl:param name = "headIdx" />
+<xsl:param name = "frozen" />
+<xsl:param name = "id" />
+<xsl:element name="table" use-attribute-sets="ricoTable">
+<xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_table ricoLG_top
+<xsl:if test="$frozen">ricoLG_left</xsl:if>
+<xsl:if test="not($frozen)">ricoLG_right</xsl:if>
+</xsl:attribute>
+<xsl:element name="thead">
+ <xsl:for-each select="$rows">
+ <xsl:choose>
+ <xsl:when test="position() = $headIdx">
+ <xsl:apply-templates select="." mode="convertHeadRow">
+ <xsl:with-param name="id" select="concat($id,'_main')"/>
+ <xsl:with-param name="frozen" select="$frozen"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="." mode="convertHeadRow">
+ <xsl:with-param name="id" select="concat($id,'_',position())"/>
+ <xsl:with-param name="frozen" select="$frozen"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+</xsl:element>
+<tbody />
+</xsl:element>
+</xsl:template>
+
+
+<xsl:template match="*" mode="convertHeadRow">
+<xsl:param name = "id" />
+<xsl:param name = "frozen" />
+ <xsl:variable name="class" select="@class"/>
+ <xsl:variable name="cells" select="xhtml:th | xhtml:td"/>
+ <xsl:element name="tr">
+ <xsl:if test="$id">
+ <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
+ </xsl:if>
+ <xsl:attribute name="class">ricoLG_hdg <xsl:value-of select="$class"/></xsl:attribute>
+ <xsl:for-each select="$cells[@class='ricoFrozen' and $frozen or not(@class='ricoFrozen') and not($frozen)]">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <div class='ricoLG_col' style='width:100px'>
+ <xsl:element name="div">
+ <xsl:attribute name="class">ricoLG_cell <xsl:value-of select="@class"/></xsl:attribute>
+ <xsl:copy-of select="* | @*[name()!='class'] | text()"/>
+ </xsl:element>
+ </div>
+ </xsl:copy>
+ </xsl:for-each>
+ </xsl:element>
+</xsl:template>
+
+
+<!-- Convert tbody section -->
+
+<xsl:template name="convertTBody">
+<xsl:param name = "rows" />
+<xsl:param name = "cols" />
+<xsl:param name = "id" />
+<xsl:param name = "frozen" />
+<xsl:element name="table" use-attribute-sets="ricoTable">
+<xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
+<xsl:attribute name="class">ricoLG_table ricoLG_bottom
+<xsl:if test="$frozen">ricoLG_left</xsl:if>
+<xsl:if test="not($frozen)">ricoLG_right</xsl:if>
+</xsl:attribute>
+<xsl:element name="tbody">
+ <tr>
+ <xsl:for-each select="$cols">
+ <xsl:if test="@class='ricoFrozen' and $frozen or not(@class='ricoFrozen') and not($frozen)">
+ <xsl:variable name="colpos" select="position()"/>
+ <td>
+ <div class='ricoLG_col' style='width:100px'>
+ <xsl:for-each select="$rows">
+ <xsl:element name="div">
+ <xsl:attribute name="class">ricoLG_cell <xsl:value-of select="xhtml:td[$colpos]/@class"/></xsl:attribute>
+ <xsl:copy-of select="xhtml:td[$colpos]/* | xhtml:td[$colpos]/@*[name()!='class'] | xhtml:td[$colpos]/text()"/>
+ </xsl:element>
+ </xsl:for-each>
+ </div>
+ </td>
+ </xsl:if>
+ </xsl:for-each>
+ </tr>
+</xsl:element>
+</xsl:element>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<xsl:stylesheet version="1.0"
+ xmlns="urn:schemas-microsoft-com:office:spreadsheet"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ xmlns:o="urn:schemas-microsoft-com:office:office"
+ xmlns:x="urn:schemas-microsoft-com:office:excel"
+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
+
+<xsl:output method="xml" indent="yes" omit-xml-declaration="no" media-type="application/xml"/>
+
+<xsl:template match="/">
+ <xsl:processing-instruction name="mso-application">
+ <xsl:text>progid="Excel.Sheet"</xsl:text>
+ </xsl:processing-instruction>
+
+ <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
+ xmlns:o="urn:schemas-microsoft-com:office:office"
+ xmlns:x="urn:schemas-microsoft-com:office:excel"
+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
+ xmlns:html="http://www.w3.org/TR/REC-html40">
+
+ <Styles>
+ <Style ss:ID="Default" ss:Name="Normal">
+ <Alignment ss:Vertical="Bottom"/>
+ <Borders/>
+ <Font/>
+ <Interior/>
+ <NumberFormat/>
+ <Protection/>
+ </Style>
+ <Style ss:ID="s21">
+ <Font ss:Bold="1"/>
+ <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
+ </Style>
+ <Style ss:ID="s22">
+ <Alignment ss:Horizontal="Left" ss:Vertical="Bottom"/>
+ <Font ss:Bold="1"/>
+ <Interior ss:Color="#99CCFF" ss:Pattern="Solid"/>
+ </Style>
+ <Style ss:ID="s23" ss:Name="Currency">
+ <NumberFormat
+ ss:Format="_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)"/>
+ </Style>
+ <Style ss:ID="s24">
+ <NumberFormat ss:Format="_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)"/>
+ </Style>
+ <Style ss:ID="s25">
+ <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
+ </Style>
+ </Styles>
+
+ <xsl:apply-templates mode="top"/>
+
+ </Workbook>
+</xsl:template>
+
+
+<xsl:template match="*" mode="top">
+ <xsl:choose>
+
+ <xsl:when test="xhtml:table[@class='ricoSimpleGrid']">
+ <xsl:apply-templates mode="grid"/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:apply-templates select="*" mode="top"/>
+ </xsl:otherwise>
+
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="*" mode="grid">
+
+ <xsl:choose>
+
+ <xsl:when test="xhtml:thead">
+ <xsl:call-template name="processTable">
+ <xsl:with-param name="id" select="@id"/>
+ <xsl:with-param name="headRows" select="xhtml:thead/xhtml:tr"/>
+ <xsl:with-param name="bodyRows" select="xhtml:tbody/xhtml:tr"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="xhtml:tbody">
+ <xsl:call-template name="processTable">
+ <xsl:with-param name="id" select="@id"/>
+ <xsl:with-param name="headRows" select="xhtml:tbody/xhtml:tr[1]"/>
+ <xsl:with-param name="bodyRows" select="xhtml:tbody/xhtml:tr[position() > 1]"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:call-template name="processTable">
+ <xsl:with-param name="id" select="@id"/>
+ <xsl:with-param name="headRows" select="xhtml:tr[1]"/>
+ <xsl:with-param name="bodyRows" select="xhtml:tr[position() > 1]"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+
+ </xsl:choose>
+
+</xsl:template>
+
+
+<!-- Perform the actual table transformation -->
+
+<xsl:template name="processTable">
+<xsl:param name="id" />
+<xsl:param name="headRows" />
+<xsl:param name="bodyRows" />
+
+ <Worksheet>
+ <xsl:attribute name="ss:Name">
+ <xsl:value-of select='$id'/>
+ </xsl:attribute>
+ <Table>
+
+ <xsl:apply-templates select="$headRows" mode="convertHeadRow"/>
+ <xsl:apply-templates select="$bodyRows" mode="convertBodyRow"/>
+
+ </Table>
+ </Worksheet>
+
+</xsl:template>
+
+
+<xsl:template match="*" mode="convertHeadRow">
+ <Row>
+ <xsl:apply-templates select="xhtml:td | xhtml:th" mode="convertHeadCell"/>
+ </Row>
+</xsl:template>
+
+
+<xsl:template match="*" mode="convertHeadCell">
+ <xsl:element name="Cell">
+ <xsl:attribute name="ss:StyleID">s22</xsl:attribute>
+ <xsl:if test="@colspan">
+ <xsl:attribute name="ss:MergeAcross"><xsl:value-of select="number(@colspan)-1"/></xsl:attribute>
+ </xsl:if>
+ <Data ss:Type="String">
+ <xsl:value-of select="."/>
+ </Data>
+ </xsl:element>
+</xsl:template>
+
+
+<xsl:template match="*" mode="convertBodyRow">
+ <Row>
+ <xsl:apply-templates select="xhtml:td | xhtml:th" mode="convertBodyCell"/>
+ </Row>
+</xsl:template>
+
+
+<xsl:template match="*" mode="convertBodyCell">
+ <Cell><Data ss:Type="String"><xsl:value-of select="."/></Data></Cell>
+</xsl:template>
+
+</xsl:stylesheet>
\ 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.
+ **/
+
+//-------------------- 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 = Element.getStyle(elem, "background-color");
+
+ // if color is tranparent, check parent
+ // Safari returns "rgba(0, 0, 0, 0)", which means transparent
+ if ( actualColor.match(/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/i) && 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 == "fromElement" ? this._background(e) : this.options.color;
+ var bgColor = this.options.bgColor == "fromParent" ? this._background(e.parentNode) : this.options.bgColor;
+ 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 = '0px';
+ 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; }
+}
+
+Rico.includeLoaded('ricoStyles.js');
--- /dev/null
+// Rico Tree Control
+// by Matt Brown
+// Oct 2006
+// email: dowdybrown@yahoo.com
+
+// Requires prototype.js and ricoCommon.js
+
+// each node in nodeIndex is an Array with 6+n positions
+// node[0] is 0/1 when the node is closed/open
+// node[1] is 0/1 when the folder is closed/open
+// node[2] is 1 if the node is a leaf node
+// node[3] is the node id
+// node[4] is the node description
+// node[5] is 1 when the node is selectable, 0 otherwise
+// node[6]...node[6+n] are the child nodes
+
+Rico.TreeControl = Class.create();
+
+Rico.TreeControl.prototype = {
+
+ initialize: function(id,url,options) {
+ Object.extend(this, new Rico.Popup({ignoreClicks:true}));
+ Object.extend(this.options, {
+ nodeIdDisplay:'none', // first, last, tooltip, or none
+ showCheckBox: false,
+ showFolders: false,
+ showPlusMinus: true,
+ defaultAction: this.nodeClick.bindAsEventListener(this),
+ height: '300px',
+ width: '300px',
+ leafIcon: Rico.imgDir+'doc.gif'
+ });
+ Object.extend(this.options, options || {});
+ this.img=[];
+ this.FirstChildNode=6;
+ this.nodeIndex={};
+ this.nodeCount=0;
+ this.foldersTree=0;
+ this.timeOutId=0;
+ this.id=id;
+ this.dataSource=url;
+ this.close=this.closePopup;
+ },
+
+ atLoad : function() {
+ var imgsrc = new Array("node.gif","nodelast.gif","folderopen.gif","folderclosed.gif");
+ for (i=0;i<imgsrc.length;i++) {
+ this.img[i] = new Image
+ this.img[i].src = Rico.imgDir+imgsrc[i]
+ //this.img[i].src = Rico.imgDir + imgsrc[i]
+ }
+ this.treeDiv=document.createElement("div");
+ this.treeDiv.id=this.id;
+ this.treeDiv.className='ricoTree';
+ this.treeDiv.style.height=this.options.height;
+ this.treeDiv.style.width=this.options.width;
+ this.container=document.createElement("div");
+ this.container.style.display="none"
+ this.container.className='ricoTreeContainer';
+ this.container.appendChild(this.treeDiv);
+ document.body.appendChild(this.container);
+ this.setDiv(this.container);
+ this.close();
+ },
+
+ // Building the data in the tree
+ open: function() {
+ this.openPopup();
+ if (this.nodeCount==0) this.loadXMLDoc();
+ },
+
+ loadXMLDoc: function(branchPin) {
+ var parms="id="+this.id;
+ if (branchPin) parms+="&Parent="+branchPin;
+ Rico.writeDebugMsg('Tree loadXMLDoc:\n'+parms+'\n'+this.dataSource);
+ new Ajax.Request(this.dataSource, {parameters:parms,method:'get',onComplete:this.processResponse.bind(this)});
+ },
+
+ processResponse: function(request) {
+ var response = request.responseXML.getElementsByTagName("ajax-response");
+ if (response == null || response.length != 1) return;
+ var rowsElement = response[0].getElementsByTagName('rows')[0];
+ var trs = rowsElement.getElementsByTagName("tr");
+ //alert('processResponse: '+trs.length);
+ for ( var i=0 ; i < trs.length; i++ ) {
+ var cells = trs[i].getElementsByTagName("td");
+ if (cells.length != 5) continue;
+ // cells[0]=parent node id
+ // cells[1]=node id
+ // cells[2]=description
+ // cells[3]=L/zero (leaf), C/non-zero (container)
+ // cells[4]= 0->not selectable, 1->selectable (use default action), otherwise the node is selectable and cells[4] contains the action
+ var content=[];
+ for (var j=0; j<cells.length; j++)
+ content[j]=this.getContent(cells[j]);
+ //content[j]=RicoUtil.getContentAsString(cells[j]);
+ var node=this.addNode(content[3],content[1],content[2],content[4]);
+ if (this.foldersTree==0) {
+ this.foldersTree = node;
+ node[0]=1;
+ node[1]=1;
+ } else {
+ var parentNode=this.nodeIndex[content[0]]
+ if (typeof parentNode=='undefined')
+ alert('ERROR!\nReceived invalid response from server - could not find parent in existing tree:\n'+content[0]);
+ else
+ parentNode.push(node);
+ }
+ }
+ if (this.nodeCount==1 && node[2])
+ this.loadXMLDoc(node[3]);
+ else
+ this.redrawTree();
+ },
+
+ getContent: function(cell) {
+ if (cell.innerHTML) return cell.innerHTML;
+ switch (cell.childNodes.length) {
+ case 0: return "";
+ case 1: return cell.firstChild.nodeValue;
+ default: return cell.childNodes[1].nodeValue;
+ }
+ },
+
+ // create new node
+ // NodeType is "C" or non-zero (container), or "L" or zero (leaf)
+ // id is the unique identifier for the node
+ // desc is the text displayed to the user
+ addNode: function(NodeType,id,desc,selectable) {
+ var arrayAux
+ //alert("addNode: " + desc + " (" + selectable + ")")
+ arrayAux = new Array
+ arrayAux[0] = 0
+ arrayAux[1] = 0
+ arrayAux[2] = (NodeType=='0' || NodeType.toUpperCase()=='L' ? 0 : 1)
+ arrayAux[3] = id
+ arrayAux[4] = desc
+ arrayAux[5] = parseInt(selectable);
+ this.nodeIndex[id]=arrayAux
+ this.nodeCount++;
+
+ return arrayAux
+ },
+
+ RemoveAllChildren: function(obj) {
+ while (obj.hasChildNodes()) {
+ this.RemoveAllChildren(obj.childNodes[0])
+ obj.removeChild(obj.childNodes[0])
+ }
+ },
+
+ redrawTree: function() {
+ //alert('redrawTree');
+ this.RemoveAllChildren(this.treeDiv)
+ this.redrawNode(this.foldersTree, 0, 1, [])
+ },
+
+ DisplayImages: function(row,arNames) {
+ var i,img,td
+ for(i=0;i<arNames.length;i++) {
+ img = document.createElement("img")
+ img.src=Rico.imgDir+arNames[i] + ".gif"
+ td=row.insertCell(-1)
+ td.appendChild(img)
+ }
+ },
+
+ redrawNode: function(foldersNode, level, lastNode, leftSide) {
+ var tab,row
+ //alert("redrawNode at level " + level + " (" + foldersNode[3] + ")")
+
+ tab = document.createElement("table")
+ tab.border=0
+ tab.cellSpacing=0
+ tab.cellPadding=0
+ row=tab.insertRow(0)
+ this.DisplayImages(row,leftSide)
+ var newLeft=leftSide.slice(0);
+ if (level>0) {
+ var suffix=lastNode ? 'last' : '';
+ if (this.options.showPlusMinus && foldersNode[2])
+ this.showPlusMinus(row.insertCell(-1),foldersNode,suffix);
+ else
+ this.NodeImage(row.insertCell(-1),suffix)
+ newLeft.push(lastNode ? "nodeblank" : "nodeline")
+ }
+ if (this.options.showFolders)
+ this.showFolders(row.insertCell(-1),foldersNode);
+ if (this.options.showCheckBox && foldersNode[5])
+ this.showCheckBox(row.insertCell(-1),foldersNode);
+ this.displayLabel(row,foldersNode)
+ this.treeDiv.appendChild(tab)
+
+ if (foldersNode.length > this.FirstChildNode && foldersNode[0]) {
+ //there are sub-nodes and the folder is open
+ for (var i=this.FirstChildNode; i<foldersNode.length;i++)
+ this.redrawNode(foldersNode[i], level+1, (i==foldersNode.length-1 ? 1 : 0), newLeft)
+ }
+ },
+
+ NodeImage: function(td, suffix) {
+ var img
+ img = document.createElement("img")
+ img.src=Rico.imgDir+"node"+suffix+".gif"
+ td.appendChild(img)
+ },
+
+
+ showPlusMinus: function(td,foldersNode,suffix) {
+ var img = document.createElement("img")
+ img.name=foldersNode[3];
+ img.style.cursor='pointer';
+ if (foldersNode.length > this.FirstChildNode)
+ img.onclick=this.openBranch.bindAsEventListener(this);
+ else
+ img.onclick=this.getChildren.bindAsEventListener(this);
+ var prefix=foldersNode[1] ? "nodem" : "nodep"
+ img.src=Rico.imgDir+prefix+suffix+".gif";
+ td.appendChild(img)
+ },
+
+ showFolders: function(td,foldersNode) {
+ var img = document.createElement("img")
+ if (!foldersNode[2]) {
+ img.src=this.options.leafIcon;
+ } else {
+ img.name=foldersNode[3];
+ img.style.cursor='pointer';
+ if (foldersNode.length > this.FirstChildNode)
+ img.onclick=this.openBranch.bindAsEventListener(this);
+ else
+ img.onclick=this.getChildren.bindAsEventListener(this);
+ img.src=Rico.imgDir+(foldersNode[1] ? "folderopen.gif" : "folderclosed.gif");
+ }
+ td.appendChild(img)
+ },
+
+ showCheckBox: function(td,foldersNode) {
+ var inp=document.createElement("input")
+ inp.type="checkbox"
+ inp.name=foldersNode[3]
+ td.appendChild(inp)
+ },
+
+ displayLabel: function(row,foldersNode) {
+ if (foldersNode[5]) {
+ var span=document.createElement('a');
+ span.href='#';
+ span.onclick=this.options.defaultAction;
+ } else {
+ var span=document.createElement('p');
+ }
+ span.id=this.id+"__"+foldersNode[3];
+ var desc=foldersNode[4];
+ switch (this.options.nodeIdDisplay) {
+ case 'last': desc+=' ('+foldersNode[3]+')'; break;
+ case 'first': desc=foldersNode[3]+' - '+desc; break;
+ case 'tooltip': span.title=foldersNode[3]; break;
+ }
+ span.appendChild(document.createTextNode(desc))
+ var td=row.insertCell(-1)
+ td.appendChild(span)
+ },
+
+ //when a parent is closed all children also are
+ closeFolders: function(foldersNode) {
+ var i=0
+ if (foldersNode[2]) {
+ for (i=this.FirstChildNode; i< foldersNode.length; i++)
+ this.closeFolders(foldersNode[i])
+ }
+ foldersNode[0] = 0
+ foldersNode[1] = 0
+ },
+
+ nodeClick: function(e) {
+ var node=Event.element(e);
+ if (this.returnValue) {
+ var v=node.id;
+ var i=v.indexOf('__');
+ if (i>=0) v=v.substr(i+2);
+ this.returnValue(v,node.innerHTML);
+ }
+ this.close();
+ },
+
+ //recurse over the tree structure
+ //called by openbranch
+ clickOnFolderRec: function(foldersNode, folderName) {
+ var i=0
+ if (foldersNode[3] == folderName) {
+ if (foldersNode[0]) {
+ this.closeFolders(foldersNode)
+ } else {
+ foldersNode[0] = 1
+ foldersNode[1] = 1
+ }
+ } else if (foldersNode[2]) {
+ for (i=this.FirstChildNode; i< foldersNode.length; i++)
+ this.clickOnFolderRec(foldersNode[i], folderName)
+ }
+ },
+
+ openBranch: function(e) {
+ var node=Event.element(e);
+ this.clickOnFolderRec(this.foldersTree, node.name)
+ this.timeOutId = setTimeout(this.redrawTree.bind(this),100)
+ },
+
+ getChildren: function(e) {
+ var node=Event.element(e);
+ this.loadXMLDoc(node.name)
+ this.openBranch(e)
+ }
+
+}
+
+Rico.includeLoaded('ricoTree.js');
--- /dev/null
+/*****************************************************************
+ Page : livegrid_DE.js
+ Description : LiveGrid text for German menus
+ Translator: rainer@langheiter@.com
+ Version 0.1 - please send corrections to dowdybrown@yahoo.com
+******************************************************************/
+// 2007-02-09, made some improvements - debach@gmx.de
+
+RicoTranslate.addPhrase("Sort by","Sortiert nach")
+RicoTranslate.addPhrase("Filter by","Gefiltert nach")
+RicoTranslate.addPhrase("Hide","Verbergen")
+RicoTranslate.addPhrase("Show","Zeige")
+RicoTranslate.addPhrase("Show All","Alle zeigen")
+RicoTranslate.addPhrase("Ascending","Aufsteigend")
+RicoTranslate.addPhrase("Descending","Absteigend")
+
+RicoTranslate.addPhrase("Include only this value","Nur diesen Wert einbeziehen")
+RicoTranslate.addPhrase("Exclude this value","Diesen Wert ausschließen")
+RicoTranslate.addPhrase("Exclude this value also","Diesen Wert ebenfalls ausschließen")
+RicoTranslate.addPhrase("Greater than or equal to this value","Größer oder gleich diesem Wert")
+RicoTranslate.addPhrase("Less than or equal to this value","Kleiner oder gleich diesem wert")
+RicoTranslate.addPhrase("Contains keyword","Enthält Schlüsselwort")
+RicoTranslate.addPhrase("Change keyword","Schlüsselwort ändern ")
+RicoTranslate.addPhrase("Enter keyword to search for","Schlüsselwort eintragen, nach dem gesucht werden soll")
+RicoTranslate.addPhrase("use * as a wildcard","verwende * als Wildcard")
+RicoTranslate.addPhrase("Remove filter","Entferne Filter")
+
+RicoTranslate.addPhrase("Waiting for data","Warte auf Daten")
+RicoTranslate.addPhrase("Request for data timed out","Zeitüberschreitung")
+
+RicoTranslate.addPhrase("No matching records","Keine übereinstimmenden Einträge")
+RicoTranslate.addPhrase("Listing records","Zeige Einträge")
+RicoTranslate.addPhrase("of","von")
+RicoTranslate.addPhrase("of about","von ungefähr")
+
+RicoTranslate.monthNames=["Januar", "Februar", "März", "April", "Mai","Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
+RicoTranslate.dayNames=["Sonntag", "Montag","Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
+
+RicoTranslate.thouSep="."
+RicoTranslate.decPoint=","
+RicoTranslate.dateFmt="dd.mm.yyyy"
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","Druck")
+RicoTranslate.addPhrase("Export","Exportiert")
+RicoTranslate.addPhrase("Visible rows","Sichtbare Zeilen")
+RicoTranslate.addPhrase("All rows","Alle Zeilen")
+
+// added for Feb 2007 release
+
+RicoTranslate.addPhrase("Loading","Lade")
+RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor Ihre Sitzung abläuft") // formal
+//RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor deine Sitzung abläuft") // informal
+//RicoTranslate.addPhrase("minutes before your session expires","Minuten, bevor die Sitzung abläuft") // indirect
+RicoTranslate.addPhrase("EXPIRED","ABGELAUFEN")
+RicoTranslate.addPhrase("Close","Schließen")
+RicoTranslate.addPhrase("Cancel","Abbrechen")
+RicoTranslate.addPhrase("Save","Speichere")
+RicoTranslate.addPhrase("Add","Erstelle")
+RicoTranslate.addPhrase("Edit","Bearbeite")
+RicoTranslate.addPhrase("Delete","Lösche")
+RicoTranslate.addPhrase("Are you sure you want to delete","Möchten Sie dies wirklich löschen:") // formal
+//RicoTranslate.addPhrase("Are you sure you want to delete","Möchtest du das wirklich löschen:") // informal
+//RicoTranslate.addPhrase("Are you sure you want to delete","Wirklich löschen:") // indirect
+RicoTranslate.addPhrase("record","Eintrag")
+RicoTranslate.addPhrase("this record","diesen Eintrag") // "dieser"?
+RicoTranslate.addPhrase("new record","neuen Eintrag") // "neuer"?
+RicoTranslate.addPhrase("Please enter","Bitte eingeben")
+RicoTranslate.addPhrase("a value for","einen Wert für")
+RicoTranslate.addPhrase("an integer value for","einen ganzzahligen Wert für")
+RicoTranslate.addPhrase("a positive integer value for","einen positiven ganzzahligen Wert für")
+RicoTranslate.addPhrase("The request returned an error","Die Anfrage ergab einen Fehler")
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Zeige Bestellungen für")
+RicoTranslate.addPhrase("Show order detail","Zeige Bestelldetails")
+RicoTranslate.addPhrase("order","Bestellung")
+RicoTranslate.addPhrase("this order","diese Bestellung")
+RicoTranslate.addPhrase("new order","neue Bestellung")
+
+// add your own here:
+
+RicoTranslate.addPhrase("Visible rows to web page","Sichtbare Zeilen auf eine Webseite")
+RicoTranslate.addPhrase("All rows to web page","Alle Zeilen auf eine Webseite")
\ No newline at end of file
--- /dev/null
+/*****************************************************************
+ Page : livegrid_es.js
+ Description : LiveGrid text for Spanish menus
+ Version 0.2 (by Marco Scarnatto)
+ If you have better translations, or would like to include
+ translations for another language, please send them to dowdybrown@yahoo.com
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","Ordenar por")
+RicoTranslate.addPhrase("Filter by","Filtrar por")
+RicoTranslate.addPhrase("Hide","Ocultar")
+RicoTranslate.addPhrase("Show","Mostrar")
+RicoTranslate.addPhrase("Show All","Mostrar todo")
+RicoTranslate.addPhrase("Ascending","Ascendente")
+RicoTranslate.addPhrase("Descending","Descendente")
+
+RicoTranslate.addPhrase("Include only this value","Incluir solo este valor")
+RicoTranslate.addPhrase("Exclude this value","Excluir este valor")
+RicoTranslate.addPhrase("Exclude this value also","Excluir este valor también")
+RicoTranslate.addPhrase("Greater than or equal to this value","Mayor o igual a este valor")
+RicoTranslate.addPhrase("Less than or equal to this value","Menor o igual a este valor")
+RicoTranslate.addPhrase("Contains keyword","Contiene el texto")
+RicoTranslate.addPhrase("Change keyword","Cambiar texto")
+RicoTranslate.addPhrase("Enter keyword to search for","Ingrese texto a buscar")
+RicoTranslate.addPhrase("use * as a wildcard","use * como un comodín")
+RicoTranslate.addPhrase("Remove filter","Quitar filtro")
+
+RicoTranslate.addPhrase("Waiting for data","Esperando datos")
+RicoTranslate.addPhrase("Request for data timed out","Tiempo excedido en recibir datos ")
+
+RicoTranslate.addPhrase("No matching records","No hay datos coincidentes")
+RicoTranslate.addPhrase("Listing records","Mostrando datos")
+RicoTranslate.addPhrase("of","de")
+RicoTranslate.addPhrase("of about","de alrededor de")
+
+RicoTranslate.thouSep=","
+RicoTranslate.decPoint="."
+RicoTranslate.dateFmt="dd/mm/yyyy"
+
+RicoTranslate.monthNames=['Enero','Febrero', 'Marzo', 'Abril', 'Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre']
+RicoTranslate.dayNames=['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado']
+
+// added for Aug 2006 release
+
+RicoTranslate.addPhrase("Print","Imprimir")
+RicoTranslate.addPhrase("Export","Exportar")
+RicoTranslate.addPhrase("Visible rows","Filas visibles")
+RicoTranslate.addPhrase("All rows","Todas las filas")
+
+// added for Feb 2007 release
+
+RicoTranslate.addPhrase("Loading","Cargar")
+RicoTranslate.addPhrase("minutes before your session expires","minutos antes de su sesión expiran")
+RicoTranslate.addPhrase("EXPIRED","EXPIRADO")
+RicoTranslate.addPhrase("Close","Cerrar")
+RicoTranslate.addPhrase("Cancel","Cancelar")
+RicoTranslate.addPhrase("Save","Guardar")
+RicoTranslate.addPhrase("Add","Añadir")
+RicoTranslate.addPhrase("Edit","Editar")
+RicoTranslate.addPhrase("Delete","Borrar")
+RicoTranslate.addPhrase("Are you sure you want to delete","¿Está seguro de que quiere borrar")
+RicoTranslate.addPhrase("record","expediente")
+RicoTranslate.addPhrase("this record","este expediente")
+RicoTranslate.addPhrase("new record","expediente nuevo")
+RicoTranslate.addPhrase("Please enter","Introduzca")
+RicoTranslate.addPhrase("a value for","un valor para")
+RicoTranslate.addPhrase("an integer value for","un valor del número entero para")
+RicoTranslate.addPhrase("a positive integer value for","un valor positivo del número entero para")
+RicoTranslate.addPhrase("The request returned an error","Un error ocurrió mientras que recibía datos")
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Mostrar las ordenes de")
+RicoTranslate.addPhrase("Show order detail","Mostrar detalle de la orden")
+RicoTranslate.addPhrase("order","la orden")
+RicoTranslate.addPhrase("this order","esta orden")
+RicoTranslate.addPhrase("new order","nueva orden")
+
+// add your own here:
--- /dev/null
+/*****************************************************************
+ Page : livegrid_FR.js
+ Description : LiveGrid text for French menus
+ Version 0.3 (revisions by Pierre Grellet)
+ If you have better translations, or would like to include
+ translations for another language, please send them to dowdybrown@yahoo.com
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","Trier par")
+RicoTranslate.addPhrase("Filter by","Filtrer par")
+RicoTranslate.addPhrase("Hide","Masquer")
+RicoTranslate.addPhrase("Show","Afficher")
+RicoTranslate.addPhrase("Show All","Afficher tous")
+RicoTranslate.addPhrase("Ascending","Croissant")
+RicoTranslate.addPhrase("Descending","Décroissant")
+
+RicoTranslate.addPhrase("Include only this value","Inclure seulement cette valeur")
+RicoTranslate.addPhrase("Exclude this value","Exclure cette valeur aussi")
+RicoTranslate.addPhrase("Exclude this value also","Exclure cette valeur")
+RicoTranslate.addPhrase("Greater than or equal to this value","Supérieur ou égal à cette valeur")
+RicoTranslate.addPhrase("Less than or equal to this value","Inférieur ou égal à cette valeur")
+RicoTranslate.addPhrase("Contains keyword","Contenant le mot-clé")
+RicoTranslate.addPhrase("Change keyword","Changer le mot-clé")
+RicoTranslate.addPhrase("Enter keyword to search for","Écrivez le mot-clé à rechercher")
+RicoTranslate.addPhrase("use * as a wildcard","utiliser * comme caractère générique")
+RicoTranslate.addPhrase("Remove filter","Enlever le filtre")
+
+RicoTranslate.addPhrase("Waiting for data","En attente des données")
+RicoTranslate.addPhrase("Request for data timed out","La requête a atteint sa limite de temps ")
+
+RicoTranslate.addPhrase("No matching records","Aucun articles ne correspond")
+RicoTranslate.addPhrase("Listing records","Résultats")
+RicoTranslate.addPhrase("of","de")
+RicoTranslate.addPhrase("of about","sur un total d'environ")
+
+RicoTranslate.thouSep="'"
+RicoTranslate.decPoint="."
+RicoTranslate.dateFmt="dd.mm.yyyy"
+
+RicoTranslate.monthNames=['Janvier','Février', 'Mars', 'Avril', 'Mai','Juin', 'Juillet','Août','Septembre','Octobre','Novembre','Décembre']
+RicoTranslate.dayNames=['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi']
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","Imprimer")
+RicoTranslate.addPhrase("Export","Exporter")
+RicoTranslate.addPhrase("Visible rows","Rangs visible")
+RicoTranslate.addPhrase("All rows","Tous les rangs")
+
+// added for Feb 2007 release
+
+RicoTranslate.addPhrase("Loading","Chargement")
+RicoTranslate.addPhrase("minutes before your session expires","minutes avant votre session expire")
+RicoTranslate.addPhrase("EXPIRED","EXPIRÉ")
+RicoTranslate.addPhrase("Close","Fermer")
+RicoTranslate.addPhrase("Cancel","Annuler")
+RicoTranslate.addPhrase("Save","Sauvegarder")
+RicoTranslate.addPhrase("Add","Ajouter")
+RicoTranslate.addPhrase("Edit","Éditer")
+RicoTranslate.addPhrase("Delete","Supprimer")
+RicoTranslate.addPhrase("Are you sure you want to delete","Êtes-vous sûr de vouloir supprimer")
+RicoTranslate.addPhrase("record","enregistrement")
+RicoTranslate.addPhrase("this record","cet enregistrement")
+RicoTranslate.addPhrase("new record","nouvel enregistrement")
+RicoTranslate.addPhrase("Please enter","Veuillez saisir")
+RicoTranslate.addPhrase("a value for","une valeur pour")
+RicoTranslate.addPhrase("an integer value for","un nombre entier pour")
+RicoTranslate.addPhrase("a positive integer value for","un nombre positif pour")
+RicoTranslate.addPhrase("The request returned an error","La requête a renvoyé une erreur")
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Montrer les commandes pour")
+RicoTranslate.addPhrase("Show order detail","Montrer les détails de la commande")
+RicoTranslate.addPhrase("order","la commande")
+RicoTranslate.addPhrase("this order","cette commande")
+RicoTranslate.addPhrase("new order","nouvelle commande")
+
+// add your own here:
--- /dev/null
+/*****************************************************************
+ Page : livegrid_IT.js
+ Description : LiveGrid text for Italian menus
+ Version 0.1 (these are guesses based mostly on babelfish results)
+ If you have better translations, or would like to include
+ translations for another language, please send them to dowdybrown@yahoo.com
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","Ordina per")
+RicoTranslate.addPhrase("Filter by","Filtra per")
+RicoTranslate.addPhrase("Hide","Nascondi")
+RicoTranslate.addPhrase("Show","Mostra")
+RicoTranslate.addPhrase("Show All","Mostra Tutte")
+RicoTranslate.addPhrase("Ascending","Crescente")
+RicoTranslate.addPhrase("Descending","Decrescente")
+
+RicoTranslate.addPhrase("Include only this value","Ritieni soltanto questo valore")
+RicoTranslate.addPhrase("Exclude this value","Escludi questo valore")
+RicoTranslate.addPhrase("Exclude this value also","Escludi questo valore anche")
+RicoTranslate.addPhrase("Greater than or equal to this value","Superiore o uguale a questo valore")
+RicoTranslate.addPhrase("Less than or equal to this value","Inferiore o uguale a questo valore")
+RicoTranslate.addPhrase("Contains keyword","Contiene la parola chiave")
+RicoTranslate.addPhrase("Change keyword","Cambia la parola chiave")
+RicoTranslate.addPhrase("Enter keyword to search for","Entra la parola chiave da cercare")
+RicoTranslate.addPhrase("use * as a wildcard","usa * come \"jolly\"")
+RicoTranslate.addPhrase("Remove filter","Rimuovi filtro")
+
+RicoTranslate.addPhrase("Waiting for data","Attendere per i dati")
+RicoTranslate.addPhrase("Request for data timed out","La richiesta dei dati ha raggiunto il limite di tempo")
+
+RicoTranslate.addPhrase("No matching records","Nessun articoli corrispondenti")
+RicoTranslate.addPhrase("Listing records","Risultati")
+RicoTranslate.addPhrase("of","di")
+RicoTranslate.addPhrase("of about","di circa")
+
+RicoTranslate.monthNames=["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"]
+RicoTranslate.dayNames=["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"]
+
+RicoTranslate.thouSep="."
+RicoTranslate.decPoint=","
+RicoTranslate.dateFmt="dd/mm/yyyy"
+
+// added for Feb 2007 release
+
+RicoTranslate.addPhrase("Loading","Caricamento")
+RicoTranslate.addPhrase("minutes before your session expires","minuti prima che la vostra sessione termini")
+RicoTranslate.addPhrase("EXPIRED","TERMINATA")
+RicoTranslate.addPhrase("Close","Chiudi")
+RicoTranslate.addPhrase("Cancel","Annulla")
+RicoTranslate.addPhrase("Save","Salva")
+RicoTranslate.addPhrase("Add","Aggiungi")
+RicoTranslate.addPhrase("Edit","Modifica")
+RicoTranslate.addPhrase("Delete","Cancella")
+RicoTranslate.addPhrase("Are you sure you want to delete","Siete sicuri che volete cancellare")
+RicoTranslate.addPhrase("record","registrazione")
+RicoTranslate.addPhrase("this record","qesta registrazione")
+RicoTranslate.addPhrase("new record","nuova registrazione")
+RicoTranslate.addPhrase("Please enter","Per favore inserire")
+RicoTranslate.addPhrase("a value for","un valore per")
+RicoTranslate.addPhrase("an integer value for","un numero intero per")
+RicoTranslate.addPhrase("a positive integer value for","un numero intero positivo per")
+RicoTranslate.addPhrase("The request returned an error","La richiesta ha generato un errore")
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Mostra gli ordini per")
+RicoTranslate.addPhrase("Show order detail","Mostra i dettagli dell'ordine")
+RicoTranslate.addPhrase("order","ordine")
+RicoTranslate.addPhrase("this order","questo ordine")
+RicoTranslate.addPhrase("new order","nuovo ordine")
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","Stampa")
+RicoTranslate.addPhrase("Export","Esporta")
+RicoTranslate.addPhrase("Visible rows","Righe visibili")
+RicoTranslate.addPhrase("All rows","Tutte le righe")
+
+// add your own here:
+
--- /dev/null
+/*****************************************************************
+ Page : livegrid_ja.js
+ Description : LiveGrid text for Japanese menus
+ Translator: hsur
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","ソート")
+RicoTranslate.addPhrase("Filter by","絞込み")
+RicoTranslate.addPhrase("Hide","隠す")
+RicoTranslate.addPhrase("Show","表示")
+RicoTranslate.addPhrase("Ascending","昇順")
+RicoTranslate.addPhrase("Descending","降順")
+
+RicoTranslate.addPhrase("Include only this value","この値を含む")
+RicoTranslate.addPhrase("Exclude this value","この値を除く")
+RicoTranslate.addPhrase("Greater than or equal to this value","これ以上の値")
+RicoTranslate.addPhrase("Less than or equal to this value","これ以下の値")
+RicoTranslate.addPhrase("Contains keyword","このキーワードを含む")
+RicoTranslate.addPhrase("Change keyword","キーワードを変更")
+RicoTranslate.addPhrase("Enter keyword to search for","キーワードを入力してください")
+RicoTranslate.addPhrase("use * as a wildcard","ワイルドカードとして*を使います")
+RicoTranslate.addPhrase("also","も")
+RicoTranslate.addPhrase("Remove filter","絞込みを削除")
+
+RicoTranslate.addPhrase("Waiting for data","データ取得中")
+RicoTranslate.addPhrase("Request for data timed out","タイムアウトしました")
+
+RicoTranslate.addPhrase("No matching records","一致するレコードはありません")
+RicoTranslate.addPhrase("Listing records","")
+RicoTranslate.addPhrase("of","of")
+RicoTranslate.addPhrase("of about","of about")
+
+RicoTranslate.monthNames=["1月", "2月", "3月", "4月", "5月","6月", "7月", "8月", "9月", "10月", "11月", "12月"]
+RicoTranslate.dayNames=["月","火", "水","木", "金", "土", "日"]
+
+RicoTranslate.thouSep="."
+RicoTranslate.decPoint=","
+RicoTranslate.dateFmt="yyyy/mm/dd"
+RicoTranslate.timeFmt="HH:nn:ss"
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","印刷")
+RicoTranslate.addPhrase("Export","抽出")
+RicoTranslate.addPhrase("Visible rows","Visible rows")
+RicoTranslate.addPhrase("All rows","全ての行")
+
+// add your own here:
+
--- /dev/null
+/*****************************************************************
+ Page : livegrid_pt.js (brazilian)
+ Description : LiveGrid text for Brazilian Portuguese menus
+ Version 0.1 (by Adriano Accorsi - adriano@token.com.br)
+ If you have better translations, or would like to include
+ translations for another language, please send them to dowdybrown@yahoo.com
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","Ordenar por")
+RicoTranslate.addPhrase("Filter by","Filtrar por")
+RicoTranslate.addPhrase("Hide","Ocultar")
+RicoTranslate.addPhrase("Show","Exibir")
+RicoTranslate.addPhrase("Show All","Exibir tudo")
+RicoTranslate.addPhrase("Ascending","Ascendente")
+RicoTranslate.addPhrase("Descending","Descendente")
+
+RicoTranslate.addPhrase("Include only this value","Incluir apenas este valor")
+RicoTranslate.addPhrase("Exclude this value","Excluir este valor")
+RicoTranslate.addPhrase("Greater than or equal to this value","Maior ou igual a este valor")
+RicoTranslate.addPhrase("Less than or equal to this value","Menor ou igual a este valor")
+RicoTranslate.addPhrase("Contains keyword","Contém texto")
+RicoTranslate.addPhrase("Change keyword","Alterar texto")
+RicoTranslate.addPhrase("Enter keyword to search for","Informe texto a ser pesquisado")
+RicoTranslate.addPhrase("use * as a wildcard","use * como 'coringa'")
+RicoTranslate.addPhrase("also","também")
+RicoTranslate.addPhrase("Remove filter","Remover filtro")
+
+RicoTranslate.addPhrase("Waiting for data","Aguardando dados")
+RicoTranslate.addPhrase("Request for data timed out","Tempo esgotado para espera de dados")
+
+RicoTranslate.addPhrase("No matching records","Nenhum registro encontrado.")
+RicoTranslate.addPhrase("Listing records","Listar registros")
+RicoTranslate.addPhrase("of","de")
+RicoTranslate.addPhrase("of about","de aproximadamente")
+
+RicoTranslate.thouSep="."
+RicoTranslate.decPoint=","
+RicoTranslate.dateFmt="dd/mm/yyyy"
+
+RicoTranslate.monthNames=["Janeiro", "Fevereiro", "Março", "Abril", "Maio","Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"]
+RicoTranslate.dayNames=["Domingo", "Segunda","Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","Imprimir")
+RicoTranslate.addPhrase("Export","Exportar")
+RicoTranslate.addPhrase("Visible rows","Fileiras visíveis")
+RicoTranslate.addPhrase("All rows","Todas as fileiras")
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Exibir pedidos de")
+RicoTranslate.addPhrase("Show order detail","Exibir detalhes do pedido")
+
+// add your own here:
--- /dev/null
+/*****************************************************************
+ Page : livegrid_ru.js
+ Description : LiveGrid text for Russian menus
+ Version 0.2 (by Illiya Gannitskiy,Alexey Uvarov)
+ If you have better translations, or would like to include
+ translations for another language, please send them to dowdybrown@yahoo.com
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","Ñîðòèðîâêà ïî")
+RicoTranslate.addPhrase("Filter by","Ôèëüòðàöèÿ ïî")
+RicoTranslate.addPhrase("Hide","Ñïðÿòàòü")
+RicoTranslate.addPhrase("Show","Ïîêàçàòü")
+RicoTranslate.addPhrase("Show All","Ïîêàçàòü âñå")
+RicoTranslate.addPhrase("Ascending","Âîçðàñòàþùàÿ")
+RicoTranslate.addPhrase("Descending","Óáûâàþùàÿ")
+
+RicoTranslate.addPhrase("Include only this value","Âêëþ÷èòü òîëüêî ýòî çíà÷åíèå")
+RicoTranslate.addPhrase("Exclude this value","Èñêëþ÷èòü ýòî çíà÷åíèå")
+RicoTranslate.addPhrase("Greater than or equal to this value","Áîëüøå èëè ðàâíî äàííîìó çíà÷åíèþ")
+RicoTranslate.addPhrase("Less than or equal to this value","Ìåíüøå èëè ðàâíî äàííîìó çíà÷åíèþ")
+RicoTranslate.addPhrase("Contains keyword","Ñîäåðæèò çíà÷åíèå")
+RicoTranslate.addPhrase("Change keyword","Èçìåíèòü çíà÷åíèå")
+RicoTranslate.addPhrase("Enter keyword to search for","Èñêàòü ïî êëþ÷ó")
+RicoTranslate.addPhrase("use * as a wildcard","Èñïîëüçîâàòü * äëÿ âñåõ çàïèñåé")
+RicoTranslate.addPhrase("also","òàêæå")
+RicoTranslate.addPhrase("Remove filter","Óáðàòü ôèëüòð")
+
+RicoTranslate.addPhrase("Waiting for data","Îæèäàíèå äàííûõ")
+RicoTranslate.addPhrase("Request for data timed out","Ïðåâûøåí èíòåðâàë îæèäàíèÿ äàííûõ")
+
+RicoTranslate.addPhrase("No matching records","Íåò ñîâïàäåíèé")
+RicoTranslate.addPhrase("Listing records","Ïðîñìîòð çàïèñåé")
+RicoTranslate.addPhrase("of","èç")
+RicoTranslate.addPhrase("of about","èç î")
+
+RicoTranslate.thouSep=","
+RicoTranslate.decPoint="."
+RicoTranslate.dateFmt="dd/mm/yyyy"
+
+RicoTranslate.monthNames=['ßíâàðü','Ôåâðàëü', 'Ìàðò', 'Àïðåëü', 'Ìàé','Èþíü', 'Èþëü','Àâãóñò','Ñåíòÿáðü','Îòêòÿáðü','Íîÿáðü','Äåêàáðü']
+RicoTranslate.dayNames=['Ïîíåäåëüíèê','Âòîðíèê','Ñðåäà','×åòâåðã','Ïÿòíèöà','Ñóááîòà','Âîñêðåñåíüå']
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","Ïå÷àòü")
+RicoTranslate.addPhrase("Export","Ýêñïîðò")
+RicoTranslate.addPhrase("Visible rows","Âèäèìûå çàïèñè")
+RicoTranslate.addPhrase("All rows","Âñå çàïèñè")
+
+// added for Feb 2007 release
+
+RicoTranslate.addPhrase("Loading","Çàãðóçêà")
+RicoTranslate.addPhrase("minutes before your session expires","ìèíóò äî èñòå÷åíèÿ ñåññèè")
+RicoTranslate.addPhrase("EXPIRED","ÈÑÒÅÊËÎ")
+RicoTranslate.addPhrase("Close","Çàêðûòî")
+RicoTranslate.addPhrase("Cancel","Îòìåíà")
+RicoTranslate.addPhrase("Save","Ñîõðàíèòü")
+RicoTranslate.addPhrase("Add","Äîáàâèòü")
+RicoTranslate.addPhrase("Edit","Ðåäàêòèðîâàòü")
+RicoTranslate.addPhrase("Delete","Óäàëèòü")
+RicoTranslate.addPhrase("Are you sure you want to delete","Âû óâåðåííû,÷òî õîòèòå óäàëèòü")
+RicoTranslate.addPhrase("record","çàïèñü")
+RicoTranslate.addPhrase("this record","ýòà çàïèñü")
+RicoTranslate.addPhrase("new record","íîâàÿ çàïèñü")
+RicoTranslate.addPhrase("Please enter","Ïîæàëóéñòà ââåäèòå")
+RicoTranslate.addPhrase("a value for","çíà÷åíèå äëÿ")
+RicoTranslate.addPhrase("an integer value for","öåëîå çíà÷åíèå äëÿ")
+RicoTranslate.addPhrase("a positive integer value for","ïîëîæèòåëüíîå öåëîå çíà÷åíèå äëÿ")
+RicoTranslate.addPhrase("The request returned an error","Çàïðîñ âîçâðàòèë îøèáêó")
+
+
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Ïîêàçàòü çíà÷åíèÿ äëÿ")
+RicoTranslate.addPhrase("Show order detail","Ïîêàçàòü çíà÷åíèÿ ïîäðîáíî")
+RicoTranslate.addPhrase("order","çíà÷åíèå")
+RicoTranslate.addPhrase("this order","ýòî çíà÷åíèå")
+RicoTranslate.addPhrase("new order","íîâîå çíà÷åíèå")
+
+
+// add your own here:
--- /dev/null
+/*****************************************************************
+ Page : livegrid_ua.js
+ Description : LiveGrid text for Ukrainian menus
+ Version 0.1 (by Illiya Gannitskiy,Alexey Uvarov)
+ If you have better translations, or would like to include
+ translations for another language, please send them to dowdybrown@yahoo.com
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","Cîðòóâàííÿ ïî")
+RicoTranslate.addPhrase("Filter by","Ô³ëüòðàö³ÿ ïî")
+RicoTranslate.addPhrase("Hide","Ñõîâàòè")
+RicoTranslate.addPhrase("Show","Ïîêàçàòè")
+RicoTranslate.addPhrase("Show All","Ïîêàçàòè âñå")
+RicoTranslate.addPhrase("Ascending","Çðîñòàþ÷à")
+RicoTranslate.addPhrase("Descending","Óáóâàþ÷à")
+
+RicoTranslate.addPhrase("Include only this value","Âêëþ÷èòè ò³ëüêè öå çíà÷åííÿ")
+RicoTranslate.addPhrase("Exclude this value","Âèêëþ÷èòè öå çíà÷åííÿ")
+RicoTranslate.addPhrase("Greater than or equal to this value","Á³ëüøå àáî ð³âíî äàíîìó çíà÷åííþ")
+RicoTranslate.addPhrase("Less than or equal to this value","Ìåíøå àáî ð³âíî äàíîìó çíà÷åííþ")
+RicoTranslate.addPhrase("Contains keyword","̳ñòèòü çíà÷åííÿ")
+RicoTranslate.addPhrase("Change keyword","Çì³íèòè çíà÷åííÿ")
+RicoTranslate.addPhrase("Enter keyword to search for","Øóêàòè ïî êëþ÷ó")
+RicoTranslate.addPhrase("use * as a wildcard","Âèêîðèñòîâóâàòè * äëÿ âñ³õ çàïèñ³â")
+RicoTranslate.addPhrase("also","òàêîæ")
+RicoTranslate.addPhrase("Remove filter","Ïðèáðàòè ô³ëüòð")
+
+RicoTranslate.addPhrase("Waiting for data","Î÷³êóâàííÿ äàíèõ")
+RicoTranslate.addPhrase("Request for data timed out","Ïåðåâèùåíèé ³íòåðâàë î÷³êóâàííÿ äàíèõ")
+
+RicoTranslate.addPhrase("No matching records","Íåìຠçá³ã³â")
+RicoTranslate.addPhrase("Listing records","Ïåðåãëÿä çàïèñ³â")
+RicoTranslate.addPhrase("of","ç")
+RicoTranslate.addPhrase("of about","ç î")
+
+RicoTranslate.thouSep=","
+RicoTranslate.decPoint="."
+RicoTranslate.dateFmt="dd/mm/yyyy"
+
+RicoTranslate.monthNames=['ѳ÷åíü','Ëþòèé', 'Áåðåçåíü', 'Êâ³òåíü', 'Òðàâåíü','×åðâåíü', 'Ëèïåíü','Ñåðïåíü','Âåðåñåíü','Æîâòåíü','Ëèñòîïàä','Ãðóäåíü']
+RicoTranslate.dayNames=['Ïîíåä³ëîê','³âòîðîê','Ñåðåäà','×åòâåð','Ï'ÿòíèöÿ','Ñóáîòà','Íåä³ëÿ']
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","Äðóê")
+RicoTranslate.addPhrase("Export","Åêñïîðò")
+RicoTranslate.addPhrase("Visible rows","Âèäèì³ çàïèñè")
+RicoTranslate.addPhrase("All rows","Âñ³ çàïèñè")
+
+// added for Feb 2007 release
+
+RicoTranslate.addPhrase("Loading","Çàâàíòàæåííÿ")
+RicoTranslate.addPhrase("minutes before your session expires","õâèëèí äî çàê³í÷åííÿ ñåñ³¿")
+RicoTranslate.addPhrase("EXPIRED","ÇÀʲÍ×ÈËÎÑß")
+RicoTranslate.addPhrase("Close","Çàêðèòî")
+RicoTranslate.addPhrase("Cancel","³äì³íà")
+RicoTranslate.addPhrase("Save","Çáåðåãòè")
+RicoTranslate.addPhrase("Add","Äîäàòè")
+RicoTranslate.addPhrase("Edit","Ðåäàãóâàòè")
+RicoTranslate.addPhrase("Delete","Âèäàëèòè")
+RicoTranslate.addPhrase("Are you sure you want to delete","Âè óïåâíåí³,ùî áàæàºòå âèäàëèòè")
+RicoTranslate.addPhrase("record","çàïèñ")
+RicoTranslate.addPhrase("this record","öåé çàïèñ")
+RicoTranslate.addPhrase("new record","íîâèé çàïèñ")
+RicoTranslate.addPhrase("Please enter","Áóäü ëàñêà, ââåä³òü")
+RicoTranslate.addPhrase("a value for","çíà÷åííÿ äëÿ")
+RicoTranslate.addPhrase("an integer value for","ö³ëå çíà÷åííÿ äëÿ")
+RicoTranslate.addPhrase("a positive integer value for","ïîçèòèâíå ö³ëå çíà÷åííÿ äëÿ")
+RicoTranslate.addPhrase("The request returned an error","Çàïèò ïîâåðíóâ ïîìèëêó")
+
+
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","Ïîêàçàòè çíà÷åííÿ")
+RicoTranslate.addPhrase("Show order detail","Ïîêàçàòè çíà÷åííÿ äåòàëüíî")
+RicoTranslate.addPhrase("order","Çíà÷åííÿ")
+RicoTranslate.addPhrase("this order","öå çíà÷åííÿ")
+RicoTranslate.addPhrase("new order","íîâå çíà÷åííÿ")
+
+
+// add your own here:
--- /dev/null
+/*****************************************************************
+ Page : livegrid_zh.js
+ Description : LiveGrid text for CHINA menus
+ Translator: Sam Shan at gz_shanming@yahoo.com
+ Version 0.1 - please send corrections to dowdybrown@yahoo.com
+ Version 0.2 - Updated based on Xinjun liu's comments.
+******************************************************************/
+
+RicoTranslate.addPhrase("Sort by","排序")
+RicoTranslate.addPhrase("Filter by","过滤")
+RicoTranslate.addPhrase("Hide","隐藏")
+RicoTranslate.addPhrase("Show","显示")
+RicoTranslate.addPhrase("Ascending","升序")
+RicoTranslate.addPhrase("Descending","降序")
+
+RicoTranslate.addPhrase("Include only this value","只包含此值")
+RicoTranslate.addPhrase("Exclude this value","不包含此值")
+RicoTranslate.addPhrase("Greater than or equal to this value","大于等于")
+RicoTranslate.addPhrase("Less than or equal to this value","小于等于")
+RicoTranslate.addPhrase("Contains keyword","包含关键字")
+RicoTranslate.addPhrase("Change keyword","更改关键字")
+RicoTranslate.addPhrase("Enter keyword to search for","输入关键字")
+RicoTranslate.addPhrase("use * as a wildcard","使用*通配符")
+RicoTranslate.addPhrase("also","也")
+RicoTranslate.addPhrase("Remove filter","移除过滤器")
+
+RicoTranslate.addPhrase("Waiting for data","等待接收数据")
+RicoTranslate.addPhrase("Request for data timed out","等待数据超时")
+
+RicoTranslate.addPhrase("No matching records","没有匹配的数据")
+RicoTranslate.addPhrase("Listing records","列出纪录")
+RicoTranslate.addPhrase("of","共")
+RicoTranslate.addPhrase("of about","大约")
+
+RicoTranslate.monthNames=["一月", "二月", "三月", "四月", "五月","六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
+RicoTranslate.dayNames=["星期日","星期一", "星期二","星期三", "星期四", "星期五", "星期六"]
+
+RicoTranslate.thouSep="."
+RicoTranslate.decPoint=","
+RicoTranslate.dateFmt="yyyy/mm/dd"
+
+// added for 22 August release
+
+RicoTranslate.addPhrase("Print","打印")
+RicoTranslate.addPhrase("Export","输出")
+RicoTranslate.addPhrase("Visible rows","当前显示记录")
+RicoTranslate.addPhrase("All rows","所有记录")
+
+// for demo only:
+
+RicoTranslate.addPhrase("Show orders for","显示订单")
+RicoTranslate.addPhrase("Show order detail","显示订单详情")
+
+// add your own here:
+
All trackbacks
</h2>
-<div id="showingLabel">Showing 1 - 5 of <?php echo $count ; ?></div>
+<div id="message" style="color: red;"></div>
-<div style="width: 100%">
-<div id="viewPort" style="float:left; width: 420px">
-<table id="tb_grid" style="border:0; margin:0; width: 400px">
+<div style="width: 95%">
+<span id="tb_grid_bookmark"></span>
+
+<table id="tb_grid" style="border:0; margin:0;">
+ <colgroup>
+ <col style="width:25px;" />
+ <col style="width:40px;" />
+ <col style="width:70px;" />
+ <col style="width:150px;" />
+ <col style="width:200px;"/>
+ <col style="width:25px;" />
+ </colgroup>
<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>
+ <th> </th>
+ <th>id</th>
+ <th>Date</th>
+ <th>Story</th>
+ <th>Title, Blog and Excerpt</th>
+ <th> </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>
+With selected:
+<a href="#" onclick="javascript: doDelete()"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
+<a href="#" onclick="javascript: doBlock()"><img alt="Block" border="0" src="<?php echo $plugindirurl?>silk/delete.png" /></a>
</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';
+<!--
+<textarea id='tb_grid_debugmsgs' rows='5' cols='80' style='font-size:smaller;'></textarea>
+-->
- 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);
- }
+<script type="text/javascript">
+//<![CDATA[
+ Rico.loadModule('LiveGridAjax');
+ Rico.loadModule('LiveGridMenu');
+ Rico.include('translations/livegrid_ja.js');
+ Rico.include('ricoAjaxEngine.js');
+
+ Rico.onLoad( function() {
+ var params = [
+ 'action=ajax',
+ 'type=all',
+ 'ticket=<?php echo $ticket ;?>'
+ ];
+
+ var cb = new Rico.TableColumn.checkbox('1','0');
+ var colspec = [
+ {canHide:false, type:'control', control:cb, ClassName:'aligncenter'},
+ {type:'raw'},
+ {type:'raw'},
+ ,
+ ,
+ ,
+ ];
+
+ var opts = {
+ saveColumnInfo : {width:true, filter:false, sort:false},
+ menuEvent : 'none',
+ frozenColumns : 2,
+ canSortDefault : true,
+ canHideDefault : true,
+ allowColResize : true,
+ canFilterDefault: false,
+ highlightElem : 'none',
+ columnSpecs : colspec
+ };
+
+ buffer = new Rico.Buffer.AjaxSQL('<?php echo $CONF['PluginURL'].'trackback/';?>grid.php',
+ {TimeOut:10, requestParameters:params, sortParmFmt: 'displayName'}
+ );
+ orderGrid=new Rico.LiveGrid ('tb_grid', buffer, opts);
+ orderGrid.menu=new Rico.GridMenu({});
+
+ // ajaxEngine
+ ajaxEngine = new Rico.AjaxEngine;
+ ajaxEngine.registerRequest('updateData', '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php' );
+ ajaxEngine.registerAjaxElement('message');
+ });
- window.onload = loadGrid;
+ function checkUpdateIds(){
+ var updateIds = [];
+ Rico.writeDebugMsg('check updated rows');
+ for(var i = 0; i < buffer.size; i++){
+ row = buffer.rows[i];
+ if( row[0].content && row[0].content == '1' ){
+ updateIds.push(row[1].content);
+ Rico.writeDebugMsg('id: '+row[1].content+' updated');
+ }
+ }
+ return updateIds;
+ }
+
+ function doBlock(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+ var params = [
+ 'action=doblock',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
+
+ function doDelete(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+
+ var params = [
+ 'action=dodelete',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
//]]>
</script>
</h2>
<ul>
- <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_clear&next=blocked'),ENT_QUOTES); ?>">ç¹\9dæ\82¶Î\9fç¹\9d�繧ッ縺è¼\94ï½\8c縺æº\98ã\83¨ç¹\9dゥç¹\9d�繧ッç¹\9dè\88\8cã\83£ç¹§ï½¯ç¸ºï½®ç¹§ï½¯ç¹\9dェ繧「</a></li>
- <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_spamclear&next=blocked'),ENT_QUOTES); ?>">spamè\9b»ï½¤è\9e³å£¹ï¼\86繧å¾\8câ\97\86ç¹\9då\8c»Î\9bç¹\9d�繧ッç¹\9dè\88\8cã\83£ç¹§ï½¯ç¸ºï½®ç¹§ï½¯ç¹\9dェ繧「</a></li>
+ <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_clear&next=blocked'),ENT_QUOTES); ?>">ã\83\96ã\83ã\83\83ã\82¯ã\81\95ã\82\8cã\81\9fã\83\88ã\83©ã\83\83ã\82¯ã\83\90ã\83\83ã\82¯ã\81®ã\82¯ã\83ªã\82¢</a></li>
+ <li><a href="<?php echo htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'].'trackback/index.php?action=blocked_spamclear&next=blocked'),ENT_QUOTES); ?>">spamå\88¤å®\9aã\81\95ã\82\8cã\81\9fã\83\88ã\83©ã\83\83ã\82¯ã\83\90ã\83\83ã\82¯ã\81®ã\82¯ã\83ªã\82¢</a></li>
</ul>
-<div id="showingLabel">Showing 1 - 5 of <?php echo $count ; ?></div>
+<div id="message" style="color: red;"></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">
+<div style="width: 95%">
+<span id="tb_grid_bookmark"></span>
+
+<table id="tb_grid" style="border:0; margin:0;">
+ <colgroup>
+ <col style="width:25px;" />
+ <col style="width:40px;" />
+ <col style="width:70px;" />
+ <col style="width:150px;" />
+ <col style="width:200px;"/>
+ <col style="width:25px;" />
+ </colgroup>
<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>
+ <th> </th>
+ <th>id</th>
+ <th>Date</th>
+ <th>Story</th>
+ <th>Title, Blog and Excerpt</th>
+ <th> </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>
+With selected:
+<a href="#" onclick="javascript: doUnblock()"><img alt="Unblock" border="0" src="<?php echo $plugindirurl;?>silk/accept.png" /></a>
+<a href="#" onclick="javascript: doDelete()"><img alt="Delete" border="0" src="<?php echo $plugindirurl?>silk/cross.png" /></a>
</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';
+<!--
+<textarea id='tb_grid_debugmsgs' rows='5' cols='80' style='font-size:smaller;'></textarea>
+-->
- 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);
- }
+<script type="text/javascript">
+//<![CDATA[
+ Rico.loadModule('LiveGridAjax');
+ Rico.loadModule('LiveGridMenu');
+ Rico.include('translations/livegrid_ja.js');
+ Rico.include('ricoAjaxEngine.js');
+
+ Rico.onLoad( function() {
+ var params = [
+ 'action=ajax',
+ 'type=blocked',
+ 'ticket=<?php echo $ticket ;?>'
+ ];
+
+ var cb = new Rico.TableColumn.checkbox('1','0');
+ var colspec = [
+ {canHide:false, type:'control', control:cb, ClassName:'aligncenter'},
+ {type:'raw'},
+ {type:'raw'},
+ ,
+ ,
+ ,
+ ];
+
+ var opts = {
+ saveColumnInfo : {width:true, filter:false, sort:false},
+ menuEvent : 'none',
+ frozenColumns : 2,
+ canSortDefault : true,
+ canHideDefault : true,
+ allowColResize : true,
+ canFilterDefault: false,
+ highlightElem : 'none',
+ columnSpecs : colspec
+ };
+
+ buffer = new Rico.Buffer.AjaxSQL('<?php echo $CONF['PluginURL'].'trackback/';?>grid.php',
+ {TimeOut:10, requestParameters:params, sortParmFmt: 'displayName'}
+ );
+ orderGrid=new Rico.LiveGrid ('tb_grid', buffer, opts);
+ orderGrid.menu=new Rico.GridMenu({});
+
+ // ajaxEngine
+ ajaxEngine = new Rico.AjaxEngine;
+ ajaxEngine.registerRequest('updateData', '<?php echo $CONF['PluginURL'].'trackback/';?>grid.php' );
+ ajaxEngine.registerAjaxElement('message');
+ });
- window.onload = loadGrid;
+ function checkUpdateIds(){
+ var updateIds = [];
+ Rico.writeDebugMsg('check updated rows');
+ for(var i = 0; i < buffer.size; i++){
+ row = buffer.rows[i];
+ if( row[0].content && row[0].content == '1' ){
+ updateIds.push(row[1].content);
+ Rico.writeDebugMsg('id: '+row[1].content+' updated');
+ }
+ }
+ return updateIds;
+ }
+
+ function doUnBlock(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+ var params = [
+ 'action=dounblock',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
+
+ function doDelete(){
+ var ids = checkUpdateIds();
+ if( !(ids.length && ids.length > 0) ) return ;
+
+ var params = [
+ 'action=dodelete',
+ 'ticket=<?php echo $ticket ;?>',
+ 'ids='+ids.join(',')
+ ];
+ ajaxEngine.sendRequest('updateData', {parameters: ajaxEngine._createQueryString(params, 0)});
+ orderGrid.resetContents('tb_grid');
+ buffer.fetch(-1);
+ }
//]]>
</script>
--- /dev/null
+<?php echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="object" id="tb_grid_updater">
+ <rowcount><?php echo $count; ?></rowcount>
+ <rows update_ui="true" offset="<?php echo $start; ?>" >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>0</td>
+ <td><?php echo $item['id'];?></td>
+ <td>
+ <?php echo date("Y-m-d H:i:s",$item['timestamp']);?>
+ </td>
+ <td>
+ <!--
+ <a href="<?php 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['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ -->
+ </td>
+ <td></td>
+ </tr>
+ <?php endwhile; ?>
+ </rows>
+ </response>
+</ajax-response>
--- /dev/null
+<?php echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="object" id='tb_grid_updater'>
+ <rowcount><?php echo $count; ?></rowcount>
+ <rows update_ui='true' >
+ <?php while (list(,$item) = each ($items)): ?>
+ <tr>
+ <td>0</td>
+ <td><?php echo $item['id'];?></td>
+ <td>
+ <?php echo date("Y-m-d H:i:s",$item['timestamp']);?>
+ </td>
+ <td>
+ <!--
+ <a href="<?php 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" />';?>
+ <?php echo $item['excerpt'];?>
+ <em>(<?php echo $item['blog_name'];?>)</em>
+ -->
+ </td>
+ <td></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="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file
--- /dev/null
+<?echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>';?>
+<?php global $manager; ?>
+
+<ajax-response>
+ <response type="element" id="message">
+ <?php echo $message; ?>
+ </response>
+</ajax-response>
\ No newline at end of file