*.plc-warning a:visited { text-decoration: none; color:white }
*.plc-warning a:hover { text-decoration: none; color:black }
-/* separator below the minitabs area */
-p.plc-minitabs {
+/* separator below the linetabs area */
+p.plc-linetabs {
height:15px;
}
// --------------------
drupal_set_title($title);
-//plekit_linetabs($tabs);
+plekit_linetabs($tabs);
if ( ! $persons ) {
drupal_set_message ('No account found');
/* $Id$ */
-div.minitabs {
+div.linetabs {
padding: 20px;
margin: 8px 0;
width:80%;
margin:8px auto;
}
-div.minitabs>ul {
+div.linetabs>ul {
width: 100%;
float: left;
font-size: small; /* could be specified at a higher level */
z-index:2;
}
-input.minitabs-submit {
+input.linetabs-submit {
font-family: verdana, sans-serif;
font-size: 14px;
text-align: center;
/*padding-bottom: 6px;*/
border-bottom: 0px;
}
-div.minitabs>ul>li {
+div.linetabs>ul>li {
float: left;
margin: 0;
padding: 0 8px 0 8px;
position:relative;
}
-div.minitabs>ul>li input.minitabs-submit {
+div.linetabs>ul>li input.linetabs-submit {
float: left;
font-size: 85%;
line-height: 20px;
color: #9c9;
}
-div.minitabs>ul>li input.active {
+div.linetabs>ul>li input.active {
/* border-bottom: 4px solid #696; */
/* padding-bottom: 2px; */
/* color when mouse is on button */
color: #696;
}
-#minitabs-sliding {
+#linetabs-sliding {
position: absolute;
z-index: 1;
font-size: 85%;
/*
$Id$
- Animated miniTabs by frequency decoder (http://www.frequency-decoder.com/)
+ Animated linetabs by frequency decoder (http://www.frequency-decoder.com/)
Based on an idea by Rob L Glazebrook (http://www.rootarcana.com/test/smartmini/) itself
derived from the original idea of Stephen Clark (http://www.sgclark.com/sandbox/minislide/)
*/
/* class */
-function minitabs () {
+function linetabs () {
this.currentTab = 0;
this.activeTab = 0;
this.destX = 0;
this.aHeight = 0;
}
-minitabs.prototype.init = function (div) {
+linetabs.prototype.init = function (div) {
this.ul = div.down('ul');
/* the array of <li>'s */
this.li_s = this.ul.select('li');
/* the array of active <input>'s - without any hidden one */
- this.input_s = this.ul.select('input.minitabs-submit');
+ this.input_s = this.ul.select('input.linetabs-submit');
/* attach event handlers */
this.li_s.each ( function (li) {
elem = elem.previousSibling;
if (elem.tagName && elem.tagName == "LI") pos++;
}
- minitabs_namespace.the_minitabs(elem).initSlide(pos,true);
+ linetabs_namespace.the_linetabs(elem).initSlide(pos,true);
} )
} );
this.ul.observe('mouseout', function (event) {
- var mt = minitabs_namespace.the_minitabs(event.element());
+ var mt = linetabs_namespace.the_linetabs(event.element());
mt.initSlide(mt.currentTab,true);
mt.setActive (mt.activeTab,false);
});
/* create slice object */
this.slideObj = this.ul.parentNode.appendChild(document.createElement("div"));
this.slideObj.appendChild(document.createTextNode(String.fromCharCode(160)));
- this.slideObj.id = "minitabs-sliding";
+ this.slideObj.id = "linetabs-sliding";
/* position it */
this.setSlidingTop();
};
-minitabs.prototype.initSlide = function (pos, force) {
+linetabs.prototype.initSlide = function (pos, force) {
if(!force && pos == this.activeTab) return;
this.setActive (this.activeTab,false);
this.initAnim();
};
-minitabs.prototype.setActive = function (pos,active) {
- var input=this.li_s[pos].select('input.minitabs-submit')[0];
+linetabs.prototype.setActive = function (pos,active) {
+ var input=this.li_s[pos].select('input.linetabs-submit')[0];
if (active)
input.addClassName('active');
else
input.removeClassName('active');
};
-minitabs.prototype.setSlidingTop = function () {
+linetabs.prototype.setSlidingTop = function () {
var delta=0;
/* up 5px for firefox */
/*window.console.log('agent=' + navigator.userAgent);*/
+ this.input_s[this.activeTab].offsetTop + delta ) + "px";
};
-minitabs.prototype.initAnim = function() {
+linetabs.prototype.initAnim = function() {
/* search for the input with type != hidden */
- var input=this.li_s[this.activeTab].select('input.minitabs-submit')[0];
+ var input=this.li_s[this.activeTab].select('input.linetabs-submit')[0];
this.destX = parseInt(this.li_s[this.activeTab].offsetLeft + input.offsetLeft
+ this.ul.offsetLeft);
this.destW = parseInt(input.offsetWidth);
this.setSlidingTop();
};
-minitabs.prototype.slideIt = function() {
+linetabs.prototype.slideIt = function() {
// Has the browser text size changed?
var active_li = this.li_s[this.activeTab];
}
};
-minitabs.prototype.animate = function(t,b,c,d) {
+linetabs.prototype.animate = function(t,b,c,d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
};
-minitabs.prototype.submit = function (message) {
+linetabs.prototype.submit = function (message) {
/* save activeTab before confirmation; some browsers - firefox - send mouseout during confirm .. */
var submitTab = this.activeTab;
/* ask for confirmation if message is not empty */
}
// globals
-var minitabs_namespace = {
+var linetabs_namespace = {
init: function () {
- $$('div.minitabs').each (function (div) {
+ $$('div.linetabs').each (function (div) {
/* create instance and attach it to the <div> element */
- div.minitabs = new minitabs ();
- div.minitabs.init(div);
+ div.linetabs = new linetabs ();
+ div.linetabs.init(div);
} ) ;
var intervalMethod = function () {
- $$('div.minitabs').each (function (div) {
- minitabs_namespace.the_minitabs(div).slideIt();
+ $$('div.linetabs').each (function (div) {
+ linetabs_namespace.the_linetabs(div).slideIt();
} ) ;
} ;
- minitabs_namespace.animInterval = setInterval(intervalMethod,10);
+ linetabs_namespace.animInterval = setInterval(intervalMethod,10);
},
cleanUp: function() {
- clearInterval(minitabs_namespace.animInterval);
- minitabs_namespace.animInterval = null;
+ clearInterval(linetabs_namespace.animInterval);
+ linetabs_namespace.animInterval = null;
},
resize: function (e) {
- $$('div.minitabs').each ( function (div) {
- var mt = div.minitabs;
+ $$('div.linetabs').each ( function (div) {
+ var mt = div.linetabs;
mt.initSlide(mt.activeTab,true);
} );
},
submit: function (id,message) {
- $(id).minitabs.submit(message);
+ $(id).linetabs.submit(message);
},
- // find the enclosing minitabs object
- the_minitabs: function (elem) {
- if (elem.match('div.minitabs'))
- return elem.minitabs;
+ // find the enclosing linetabs object
+ the_linetabs: function (elem) {
+ if (elem.match('div.linetabs'))
+ return elem.linetabs;
else
- return elem.up('div.minitabs').minitabs;
+ return elem.up('div.linetabs').linetabs;
}
};
-window.onload = minitabs_namespace.init;
-window.onunload = minitabs_namespace.cleanUp;
-window.onresize = minitabs_namespace.resize;
+window.onload = linetabs_namespace.init;
+window.onunload = linetabs_namespace.cleanUp;
+window.onresize = linetabs_namespace.resize;
function plekit_linetabs ($array, $id=NULL) {
// need id to pass to the onclick function attached to the input buttons
- $id="minitabs";
+ $id="linetabs";
if (! $id) $id .= '-' + $id;
- print "<div id='$id' class='minitabs'>";
+ print "<div id='$id' class='linetabs'>";
print "<ul>";
foreach ($array as $label=>$todo) {
// in case we have a simple string, rewrite it as an array
if ( $values ) foreach ($values as $key=>$value) {
print "<input type=hidden name='$key' value='$value' />";
}
- $tracer="class=minitabs-submit";
+ $tracer="class=linetabs-submit";
// image and its companions 'height'
if ($todo['image']) {
$type='type=image src="' . $todo['image'] . '"';
print "<span title='$bubble'>";
$message="";
if ($todo['confirm']) $message=$todo['confirm'] . " ?";
- print "<input $tracer $type onclick='minitabs_namespace.submit(\"$id\",\"$message\")' />";
+ print "<input $tracer $type onclick='linetabs_namespace.submit(\"$id\",\"$message\")' />";
print "</span>";
print "</form></li>\n";
}
// $Id$
+require_once 'prototype.php';
+
drupal_set_html_head('
<script type="text/javascript" src="/plekit/tablesort/tablesort.js"></script>
<script type="text/javascript" src="/plekit/tablesort/customsort.js"></script>
// instantiate paginator callback
print <<< EOF
<script type="text/javascript">
-function $paginator (opts) { plc_table_paginator (opts,"$this->table_id"); }
+function $paginator (opts) { plekit_table_paginator (opts,"$this->table_id"); }
</script>
<br/>
<table id="$this->table_id" cellpadding="0" cellspacing="0" border="0"
-class="plc_table sortable-onload-$this->column_sort rowstyle-alt colstyle-alt no-arrow $classname">
+class="plekit_table sortable-onload-$this->column_sort rowstyle-alt colstyle-alt no-arrow $classname">
<thead>
EOF;
$class="sortable";
if ( ! empty($type)) $class .= "-sort" . $type;
}
- printf ('<th class="%s plc_table">%s</th>',$class,$label);
+ printf ('<th class="%s plekit_table">%s</th>',$class,$label);
}
print <<< EOF
$result= <<< EOF
<tr class=pagesize_area><td class=pagesize_area colspan=$width><form class='pagesize'>
<input class='pagesize_input' type='text' id="$pagesize_text_id" value=$this->pagesize
- onkeyup='plc_pagesize_set("$this->table_id","$pagesize_text_id", $this->pagesize);'
+ onkeyup='plekit_pagesize_set("$this->table_id","$pagesize_text_id", $this->pagesize);'
size=3 maxlength=3 />
<label class='pagesize_label'> items/page </label>
<img class='table_reset' src="/planetlab/icons/clear.png"
- onmousedown='plc_pagesize_reset("$this->table_id","$pagesize_text_id",$this->pagesize_def);' />
+ onmousedown='plekit_pagesize_reset("$this->table_id","$pagesize_text_id",$this->pagesize_def);' />
</form></td></tr>
EOF;
return $result;
<tr class=search_area><td class=search_area colspan=$width><form class='table_search'>
<label class='table_search_label'> Search </label>
<input class='table_search_input' type='text' id='$search_text_id'
- onkeyup='plc_table_filter("$this->table_id","$search_text_id","$search_and_id");'
+ onkeyup='plekit_table_filter("$this->table_id","$search_text_id","$search_and_id");'
size=$this->search_width maxlength=256 />
<label>and</label>
<input id='$search_and_id' class='table_search_and'
type='checkbox' checked='checked'
- onchange='plc_table_filter("$this->table_id","$search_text_id","$search_and_id");' />
+ onchange='plekit_table_filter("$this->table_id","$search_text_id","$search_and_id");' />
<img class='table_reset' src="/planetlab/icons/clear.png"
- onmousedown='plc_table_filter_reset("$this->table_id","$search_text_id","$search_and_id");'>
+ onmousedown='plekit_table_filter_reset("$this->table_id","$search_text_id","$search_and_id");'>
</form></td></tr>
EOF;
return $result;
if (! $notes)
return "";
$result = "";
- $result .= "<p class='plc_table_note'> <span class='plc_table_note_title'>Notes</span>\n";
+ $result .= "<p class='plekit_table_note'> <span class='plekit_table_note_title'>Notes</span>\n";
foreach ($notes as $note)
$result .= "<br/>$note\n";
$result .= "</p>";
/* $Id$ */
-table.plc_table {
+table.plekit_table {
width: auto;
padding: 0;
margin: 0 auto 1.5em auto;
border-collapse:collapse;
}
-table.plc_table>thead>tr, table.plc_table>tbody>tr {
+table.plekit_table>thead>tr, table.plekit_table>tbody>tr {
border-left: 1px solid #C1DAD7;
}
/* remove border for search/pagesize area */
-table.plc_table>thead>tr.pagesize_area, table.plc_table>thead>tr.search_area {
+table.plekit_table>thead>tr.pagesize_area, table.plekit_table>thead>tr.search_area {
border-left: 0px;
}
-th.plc_table {
+th.plekit_table {
font: bold 10px/22px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
color: #4f6b72;
border-right: 1px solid #C1DAD7;
background: #CAE8EA url(/plekit/icons/tablesort-header.jpg) no-repeat;
vertical-align:middle;
}
-table.plc_table>tbody>tr>td, table.plc_table textarea, table.plc_table input [type="text"] {
+table.plekit_table>tbody>tr>td, table.plekit_table textarea, table.plekit_table input [type="text"] {
font: normal 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
border-right: 1px solid #C1DAD7;
border-bottom: 1px solid #C1DAD7;
}
-table.plc_table>tbody>tr>td {
+table.plekit_table>tbody>tr>td {
padding: 6px 12px 6px 12px;
color: #4f6b72;
}
tr[class="alt"]>td {
background: #F5FAFA url(/plekit/icons/tablesort-td-alt.jpg) no-repeat;
}
-table.plc_table>tbody>tr>td [class~="alt"] {
+table.plekit_table>tbody>tr>td [class~="alt"] {
background: #edf3f3 url(/plekit/icons/tablesort-col-alt.jpg) no-repeat !important;
}
/* Poor old Internet Explorer won't see the next two rules either as it doesn't get :first-child */
-table.plc_table>tbody>tr.alt>td:first-child {
+table.plekit_table>tbody>tr.alt>td:first-child {
background: #F5FAFA url(/plekit/icons/tablesort-bullet2.gif) no-repeat;
font-weight:bold;
}
-table.plc_table>tbody>tr>td:first-child {
+table.plekit_table>tbody>tr>td:first-child {
background: #fff url(/plekit/icons/tablesort-bullet1.gif) no-repeat;
font-weight:bold;
}
p.paginationText {
font-style:oblique;
}
-p.plc_table_note {
+p.plekit_table_note {
font-style:oblique;
font-size:0.6em;
font-family: georgia;
text-align: center;
}
-span.plc_table_note_title {
+span.plekit_table_note_title {
font-weight:bold;
font-size:1.5em;
font-family: georgia;
mul.fdtablePaginater {display:inline;}
ul.fdtablePaginater li {float:left;}
ul.fdtablePaginater {text-align:center;}
-/*table.plc_table { border-bottom:1px solid #C1DAD7; }*/
+/*table.plekit_table { border-bottom:1px solid #C1DAD7; }*/
+
+.table_search_input:focus {
+ background-color: #888;
+}
/* $Id$ */
/* when a table gets paginated, displays context info */
-function plc_table_paginator (opts,tablename) {
+function plekit_table_paginator (opts,table_id) {
if(!("currentPage" in opts)) { return; }
var p = document.createElement('p');
- var t = document.getElementById(tablename+'-fdtablePaginaterWrapTop');
- var b = document.getElementById(tablename+'-fdtablePaginaterWrapBottom');
+ var table=$(table_id);
+ var t = $(table_id+'-fdtablePaginaterWrapTop');
+ var b = $(table_id+'-fdtablePaginaterWrapBottom');
/* when there's no visible entry, the pagination code removes the wrappers */
if ( (!t) || (!b) ) return;
/* get how many entries are matching:
opts.visibleRows only holds the contents of the current page
- so we store the number of matching entries in the tbody's 'matching' attribute
+ so we store the number of matching entries in the table 'matching' attribute
*/
var totalMatches = opts.totalRows;
- var tbody=document.getElementById(tablename).getElementsByTagName("tbody")[0];
- var matching=tbody['matching'];
+ var matching=table['matching'];
if (matching) totalMatches = matching;
var label;
/* locates a table from its id and alters the classname to reflect new table size */
-function plc_pagesize_set (table_id,size_id,def_size) {
+function plekit_pagesize_set (table_id,size_id,def_size) {
var table=document.getElementById(table_id);
var size_area=document.getElementById(size_id);
if ( ! size_area.value ) {
tablePaginater.init(table_id);
}
-function plc_pagesize_reset(table_id, size_id, size) {
+function plekit_pagesize_reset(table_id, size_id, size) {
var table=document.getElementById(table_id);
var size_area=document.getElementById(size_id);
size_area.value=size;
}
/* set or clear the ' invisibleRow' in the tr's classname, according to visible */
-function plc_table_row_visible (row,visible) {
+function plekit_table_row_visible (row,visible) {
var cn=row.className;
/* clear */
cn=cn.replace(" invisibleRow","");
row.className=cn;
}
-// from a cell, extract visible text by removing <> and cache in 'plc_text' attribute
-var re_brackets = new RegExp ('<[^>]*>','g');
-
-function plc_table_cell_text (cell) {
- if (cell['plc_text']) return cell['plc_text'];
- var text = cell.innerHTML;
- // remove what's between <>
- text = text.replace(re_brackets,'');
- cell['plc_text'] = text;
+// Working around MSIE...
+if ('undefined' == typeof Node)
+ Node = { ELEMENT_NODE: 1, TEXT_NODE: 3 };
+
+// Extract actual text from a DOM node (remove internal tags and so on)
+function getInnerText(node) {
+ var result = '';
+ if (Node.TEXT_NODE == node.nodeType)
+ return node.nodeValue;
+ if (Node.ELEMENT_NODE != node.nodeType)
+ return '';
+ for (var index = 0; index < node.childNodes.length; ++index)
+ result += getInnerText(node.childNodes.item(index));
+ return result;
+} // getInnerText
+
+// cache in the <tr> node the concatenation of the innerTexts of its cells
+function plekit_tr_text (tr) {
+ // if cached, use it
+ if (tr['text_to_match']) return tr['text_to_match'];
+ // otherwise compute it
+ var text="";
+ var cells=tr.cells;
+ for (var i=0; i<cells.length; i++)
+ text += getInnerText(cells[i]) + " ";
+ text = text.strip().toLowerCase();
+ tr['text_to_match'] = text;
return text;
}
/* scan the table, and mark as visible
the rows that match (either AND or OR the patterns) */
-function plc_table_filter (table_id,pattern_id,and_id) {
- var tbody = document.getElementById(table_id).getElementsByTagName("tbody")[0];
- var rows=tbody.rows;
- var pattern_area = document.getElementById(pattern_id);
+function plekit_table_filter (table_id,pattern_id,and_id) {
+ var table=$(table_id);
+ var css='#'+table_id+'>tbody';
+ var rows = $$(css)[0].rows;
+ var pattern_area = $(pattern_id);
var pattern_text = pattern_area.value;
- var row_index, row, cells, cell_index, cell, visible;
var matching_entries=0;
- var and_button=document.getElementById(and_id);
+ var and_button=$(and_id);
var and_if_true=and_button.checked;
- // remove whitespaces at the beginning and end
- pattern_text = pattern_text.replace(/[ \t]+$/,"");
- pattern_text = pattern_text.replace(/^[ \t]+/,"");
+ // canonicalize white spaces
+ pattern_text = pattern_text.replace(/^\s+/, '').replace(/\s+$/, '').replace(/\s+/g,' ');
if (pattern_text.indexOf ("&") != -1) {
pattern_text = pattern_text.replace(/&/," ");
var match_attempts=0;
var start=(new Date).getTime();
- // re compile all patterns - ignore case
- var pattern_texts = pattern_text.split(" ");
+ // if we're running with the same pattern
+ var previous_pattern=table['previous_pattern'];
+ var previous_mode=table['previous_mode'];
+ if ( (previous_pattern == pattern_text) && (previous_mode == and_if_true) ) {
+ window.console.log ('no change in pattern');
+ return;
+ }
+
+ // re compile all patterns
+ var pattern_texts = pattern_text.strip().split(" ");
+ var searches=new Array();
var patterns=new Array();
for (var i=0; i < pattern_texts.length; i++) {
- window.console.log ('compiled ' + i + '-th pattern = <' + pattern_texts[i] + '>');
+ window.console.log ('compiled ' + i + '-th pattern = [' + pattern_texts[i] + ']');
+ // ignore case
+ searches[i]=pattern_texts[i].toLowerCase();
patterns[i]=new RegExp(pattern_texts[i],"i");
}
- // scan rows
- for (row_index = 0; row=rows[row_index]; row_index++) {
- cells=row.cells;
+ // scan rows, elaborate 'visible'
+ window.console.log ('we have ' + rows.length + ' rows');
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+ var visible=false;
/*empty pattern */
if (patterns.length == 0) {
} else if (and_if_true) {
/* AND mode: all patterns must match */
visible=true;
- for (i in patterns) {
- var matched=false;
- var pattern=patterns[i];
- for (cell_index = 0; cell=cells[cell_index]; cell_index++) {
- var against=plc_table_cell_text (cell);
- match_attempts++;
- if ( against.match(pattern)) {
- matched=true;
- break;
- }
+ var against=plekit_tr_text (tr);
+ for (var search_index=0; search_index<searches.length; search_index++) {
+ var search=searches[search_index];
+ match_attempts++;
+ if ( against.search(search) < 0) {
+ visible=false;
+ break;
}
- if ( ! matched ) visible=false;
}
} else {
/* OR mode: any match is good enough */
visible=false;
- for (cell_index = 0; cell=cells[cell_index]; cell_index++) {
- var against = cell.plc_table_cell_text(cell);
- for (i in patterns) {
- pattern=patterns[i];
- match_attempts++;
- if (against.match(pattern)) {
- visible=true;
- // alert ('OR matched! p='+pattern+' c='+cell.innerHTML);
- break;
- }
+ var against = plekit_tr_text(tr);
+ for (var search_index=0; search_index < searches.length; search_index++) {
+ var search=searches[search_index];
+ match_attempts++;
+ if (against.search(search) >= 0) {
+ visible=true;
+ break;
}
}
}
- plc_table_row_visible(row,visible);
+
+ plekit_table_row_visible(tr,visible);
if (visible) matching_entries +=1;
}
+ // save for next run
+ table['previous_pattern']=pattern_text;
+ table['previous_mode']=and_if_true;
+
var end=(new Date).getTime();
- var ms=end-start;
- window.console.log ("plc_table_filter: " +
- match_attempts + " matches - " +
- matching_entries + " lines - " + ms + " ms");
- tbody['matching']=matching_entries;
- tbody['match_attempts']=match_attempts;
+ var match_ms=end-start;
+
+ // optimize useless calls to init, by comparing # of matching entries
+ var previous_matching=table['previous_matching'];
+ if (matching_entries == previous_matching) {
+ window.console.log ('same # of matching entries - skipped redisplay');
+ window.console.log ("plekit_table_filter: " +
+ match_attempts + " matches - " +
+ matching_entries + " lines - "
+ + "match=" + match_ms + " ms");
+ return;
+ }
+
+ table['matching']=matching_entries;
+ table['match_attempts']=match_attempts;
tablePaginater.init(table_id);
+ var end2=(new Date).getTime();
+ var paginate_ms=end2-end;
+ window.console.log ("plekit_table_filter: " +
+ match_attempts + " matches - " +
+ matching_entries + " lines - "
+ + "match=" + match_ms + " ms - "
+ + "paginate=" + paginate_ms + " ms");
+
}
-function plc_table_filter_reset (table_id, pattern_id,and_id) {
+function plekit_table_filter_reset (table_id, pattern_id,and_id) {
/* reset pattern */
document.getElementById(pattern_id).value="";
- plc_table_filter (table_id, pattern_id,and_id);
+ plekit_table_filter (table_id, pattern_id,and_id);
}