From: Thierry Parmentelat Date: Wed, 25 Feb 2009 19:40:42 +0000 (+0000) Subject: optimized for speed - OK for nodes, but 4000+ persons is still one second per keystro... X-Git-Tag: PLEWWW-4.3-1~28 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=9d738b9c70ffa2c737b4d8256801763cd4fe37a5;p=plewww.git optimized for speed - OK for nodes, but 4000+ persons is still one second per keystroke... --- diff --git a/planetlab/css/plc_style.css b/planetlab/css/plc_style.css index 5d3e791..670d252 100644 --- a/planetlab/css/plc_style.css +++ b/planetlab/css/plc_style.css @@ -39,7 +39,7 @@ body { *.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; } diff --git a/planetlab/persons/persons.php b/planetlab/persons/persons.php index ca4cb78..ccc4219 100644 --- a/planetlab/persons/persons.php +++ b/planetlab/persons/persons.php @@ -127,7 +127,7 @@ foreach ($sites as $site) { // -------------------- drupal_set_title($title); -//plekit_linetabs($tabs); +plekit_linetabs($tabs); if ( ! $persons ) { drupal_set_message ('No account found'); diff --git a/plekit/linetabs/linetabs.css b/plekit/linetabs/linetabs.css index fe364ae..8f44090 100644 --- a/plekit/linetabs/linetabs.css +++ b/plekit/linetabs/linetabs.css @@ -1,12 +1,12 @@ /* $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 */ @@ -18,7 +18,7 @@ div.minitabs>ul { z-index:2; } -input.minitabs-submit { +input.linetabs-submit { font-family: verdana, sans-serif; font-size: 14px; text-align: center; @@ -29,7 +29,7 @@ input.minitabs-submit { /*padding-bottom: 6px;*/ border-bottom: 0px; } -div.minitabs>ul>li { +div.linetabs>ul>li { float: left; margin: 0; padding: 0 8px 0 8px; @@ -38,7 +38,7 @@ div.minitabs>ul>li { position:relative; } -div.minitabs>ul>li input.minitabs-submit { +div.linetabs>ul>li input.linetabs-submit { float: left; font-size: 85%; line-height: 20px; @@ -49,14 +49,14 @@ div.minitabs>ul>li input.minitabs-submit { 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%; diff --git a/plekit/linetabs/linetabs.js b/plekit/linetabs/linetabs.js index 5e89f0f..8ecf5eb 100644 --- a/plekit/linetabs/linetabs.js +++ b/plekit/linetabs/linetabs.js @@ -1,7 +1,7 @@ /* $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/) @@ -14,7 +14,7 @@ */ /* class */ -function minitabs () { +function linetabs () { this.currentTab = 0; this.activeTab = 0; this.destX = 0; @@ -28,12 +28,12 @@ function minitabs () { this.aHeight = 0; } -minitabs.prototype.init = function (div) { +linetabs.prototype.init = function (div) { this.ul = div.down('ul'); /* the array of
  • 's */ this.li_s = this.ul.select('li'); /* the array of active '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) { @@ -47,12 +47,12 @@ minitabs.prototype.init = function (div) { 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); }); @@ -65,7 +65,7 @@ minitabs.prototype.init = function (div) { /* 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(); @@ -79,7 +79,7 @@ minitabs.prototype.init = function (div) { }; -minitabs.prototype.initSlide = function (pos, force) { +linetabs.prototype.initSlide = function (pos, force) { if(!force && pos == this.activeTab) return; this.setActive (this.activeTab,false); @@ -88,15 +88,15 @@ minitabs.prototype.initSlide = function (pos, force) { 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);*/ @@ -105,9 +105,9 @@ minitabs.prototype.setSlidingTop = function () { + 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); @@ -121,7 +121,7 @@ minitabs.prototype.initAnim = function() { this.setSlidingTop(); }; -minitabs.prototype.slideIt = function() { +linetabs.prototype.slideIt = function() { // Has the browser text size changed? var active_li = this.li_s[this.activeTab]; @@ -144,12 +144,12 @@ minitabs.prototype.slideIt = function() { } }; -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 */ @@ -161,48 +161,48 @@ minitabs.prototype.submit = function (message) { } // 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
    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; diff --git a/plekit/php/linetabs.php b/plekit/php/linetabs.php index 3e89eab..41f211e 100644 --- a/plekit/php/linetabs.php +++ b/plekit/php/linetabs.php @@ -47,9 +47,9 @@ drupal_set_html_head(' 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 "
    "; + print "
    "; print "
      "; foreach ($array as $label=>$todo) { // in case we have a simple string, rewrite it as an array @@ -77,7 +77,7 @@ function plekit_linetabs ($array, $id=NULL) { if ( $values ) foreach ($values as $key=>$value) { print ""; } - $tracer="class=minitabs-submit"; + $tracer="class=linetabs-submit"; // image and its companions 'height' if ($todo['image']) { $type='type=image src="' . $todo['image'] . '"'; @@ -89,7 +89,7 @@ function plekit_linetabs ($array, $id=NULL) { print ""; $message=""; if ($todo['confirm']) $message=$todo['confirm'] . " ?"; - print ""; + print ""; print ""; print "\n"; } diff --git a/plekit/php/table.php b/plekit/php/table.php index 65ea41a..4072d2e 100644 --- a/plekit/php/table.php +++ b/plekit/php/table.php @@ -2,6 +2,8 @@ // $Id$ +require_once 'prototype.php'; + drupal_set_html_head(' @@ -86,11 +88,11 @@ class PlekitTable { // instantiate paginator callback print <<< EOF
      +class="plekit_table sortable-onload-$this->column_sort rowstyle-alt colstyle-alt no-arrow $classname"> EOF; @@ -110,7 +112,7 @@ EOF; $class="sortable"; if ( ! empty($type)) $class .= "-sort" . $type; } - printf ('',$class,$label); + printf ('',$class,$label); } print <<< EOF @@ -138,11 +140,11 @@ EOF; $result= <<< EOF EOF; return $result; @@ -158,14 +160,14 @@ EOF; EOF; return $result; @@ -203,7 +205,7 @@ EOF; if (! $notes) return ""; $result = ""; - $result .= "

      Notes\n"; + $result .= "

      Notes\n"; foreach ($notes as $note) $result .= "
      $note\n"; $result .= "

      "; diff --git a/plekit/table/table.css b/plekit/table/table.css index b2f23f5..34bc799 100644 --- a/plekit/table/table.css +++ b/plekit/table/table.css @@ -1,19 +1,19 @@ /* $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; @@ -26,12 +26,12 @@ th.plc_table { 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; } @@ -78,15 +78,15 @@ tr.alt { 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; } @@ -220,13 +220,13 @@ tr.invisibleRow { 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; @@ -238,4 +238,8 @@ ul.fdtablePaginater {display:inline-block;} 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; +} diff --git a/plekit/table/table.js b/plekit/table/table.js index 6fa8ca1..5851acd 100644 --- a/plekit/table/table.js +++ b/plekit/table/table.js @@ -1,24 +1,24 @@ /* $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; @@ -44,7 +44,7 @@ function plc_table_paginator (opts,tablename) { /* 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 ) { @@ -55,7 +55,7 @@ function plc_pagesize_set (table_id,size_id,def_size) { 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; @@ -64,7 +64,7 @@ function plc_pagesize_reset(table_id, size_id, 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",""); @@ -72,33 +72,50 @@ function plc_table_row_visible (row,visible) { 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 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; itbody'; + 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(/&/," "); @@ -115,17 +132,30 @@ function plc_table_filter (table_id,pattern_id,and_id) { 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) { @@ -133,50 +163,65 @@ function plc_table_filter (table_id,pattern_id,and_id) { } 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
      %s%s
      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 /> + onmousedown='plekit_pagesize_reset("$this->table_id","$pagesize_text_id",$this->pagesize_def);' />