Hi, I'm finding the current guide in the web interface rather useless. It takes 35-40 seconds to get the guide (with a few hundred channels) to display on my browser; this includes about 30 seconds on the server, and 10 seconds on the client to render the page. Obviously this is unacceptable.
I reserve the right to use words like "useless" and "unacceptable" because I'm attaching a fix. :) Back in March there was an exchange on this list about how to improve the guide for the web interface. This patch implements the ideas I mocked up as described here: http://sourceforge.net/mailarchive/message.php?msg_id=7387214 The web interface code is scary. I don't mean to insult anyone, so I'll give the author the benefit of the doubt and assume he scratched something quickly together without giving it much thought. :) The obscene performance of the guide can be attributed to two things: 1. Server side: egregious string concatenation. Python is slow at concatenating strings when they grow very big. I learned this quickly with my bmovl2 work. An easy and significant performance fix is to use a list, and string.join(list, "\n") when you're done. 2. Client side: A unique hidden div was created for every program in the displayed guide. There are clever adjectives I could use to describe this. I'll leave them to your imagination. Suffice it to say the browser takes a fair bit of time to churn through all this code. Fixing #1 realized significant improvement: from 40 seconds to 7 seconds. Unfortunately the HTMLResource stuff doesn't seem to allow for this very well. Fixing this The Right Way would involve reworking the underlying code. I didn't want to sign up for that. :) Instead I just removed the tableRowOpen/tableRowClose/tableCell stuff on the inner loop and hard-coded the HTML, adding the lines to the array. The end justifies the means. Fixing #2 was relatively straight forward, and it's detailed in my email at the URL above, so I won't repeat it here. Now when you click on a grid cell, the window pops up saying "Fetching data from server" and it loads proginfo.rpy from the server, which then dynamically updates the popup's contents via Javascript. Fix #2 also applied to genre.rpy. I also fixed a couple other bugs I ran into. edit_favorite.rpy was generating a JS error because some script code wasn't separated by a newline. There was also some rendering glitches in that page because there was a missing hack. This patch is against 1.5.0, but it applies to cvs. Code tested in Firefox and IE 6.0. Cheers, Jason.
diff -Naur htdocs.old/edit_favorite.rpy htdocs/edit_favorite.rpy
--- htdocs.old/edit_favorite.rpy 2004-05-20 11:45:07.000000000 -0400
+++ htdocs/edit_favorite.rpy 2004-08-09 23:41:08.769874880 -0400
@@ -190,13 +190,14 @@
guide = tv.epg_xmltv.get_guide()
fv.printHeader(_('Edit Favorite'), 'styles/main.css')
-
- fv.tableOpen('border="0" cellpadding="4" cellspacing="1" width="100%"')
- fv.tableRowOpen('class="chanrow"')
- fv.tableCell('<img src="images/logo_200x100.png" />', 'align="left"')
- fv.tableCell(_('Edit Favorite'), 'class="heading" align="left"')
- fv.tableRowClose()
- fv.tableClose()
+ fv.res += ' <br/>\n'
+ # This seems out of place.
+ #fv.tableOpen('border="0" cellpadding="4" cellspacing="1" width="100%"')
+ #fv.tableRowOpen('class="chanrow"')
+ #fv.tableCell('<img src="images/logo_200x100.png" />', 'align="left"')
+ #fv.tableCell(_('Edit Favorite'), 'class="heading" align="left"')
+ #fv.tableRowClose()
+ #fv.tableClose()
fv.res += '<br><form name="editfavorite" method="get" action="favorites.rpy">'
@@ -322,20 +323,20 @@
fv.res += '<script language="JavaScript">'
if fav.channel == 'ANY':
- fv.res += 'document.editfavorite.chan.options[0].selected=true'
+ fv.res += 'document.editfavorite.chan.options[0].selected=true\n'
else:
- fv.res += 'document.editfavorite.chan.options[%s].selected=true' % chan_index
+ fv.res += 'document.editfavorite.chan.options[%s].selected=true\n' % chan_index
if fav.dow == 'ANY':
- fv.res += 'document.editfavorite.dow.options[0].selected=true'
+ fv.res += 'document.editfavorite.dow.options[0].selected=true\n'
else:
- fv.res += 'document.editfavorite.dow.options[(1+%s)].selected=true' % fav.dow
+ fv.res += 'document.editfavorite.dow.options[(1+%s)].selected=true\n' % fav.dow
if fav.mod == 'ANY':
- fv.res += 'document.editfavorite.mod.options[0].selected=true'
+ fv.res += 'document.editfavorite.mod.options[0].selected=true\n'
else:
mod_index = int(fav.mod)/30 + 1
- fv.res += 'document.editfavorite.mod.options[%s].selected=true' % mod_index
+ fv.res += 'document.editfavorite.mod.options[%s].selected=true\n' % mod_index
fv.res += '</script>'
diff -Naur htdocs.old/genre.rpy htdocs/genre.rpy
--- htdocs.old/genre.rpy 2004-03-04 21:37:05.000000000 -0500
+++ htdocs/genre.rpy 2004-08-10 00:40:10.100510792 -0400
@@ -159,7 +159,6 @@
fv.tableCell('Stop', 'class="guidehead"')
fv.tableRowClose()
- pops = ''
desc = ''
gotdata = 0
for chan in guide.chan_list:
@@ -190,77 +189,8 @@
fv.tableRowOpen('class="chanrow"')
fv.tableCell(chan.displayname, 'class="channel"')
popid = '%s:%s' % (prog.channel_id, prog.start)
- if prog.desc == '':
- desc = _('Sorry, the program description for %s is unavailable.') % ('<b>'+prog.title+'</b>')
- else:
- desc = prog.desc
- pops += ( u"<div id=\"%s\" class=\"proginfo\">\n"\
- u" <table width=\"100%%\"\n"\
- u" cellpadding=\"0\"\n"\
- u" cellspacing=\"0\"\n"\
- u" class=\"popup\"\n"\
- u" onmouseover=\"focusPop('%s');\"\n"\
- u" onmouseout=\"unfocusPop('%s');\">\n"\
- u" <thead>\n"\
- u" <tr>\n"\
- u" <td>"\
- u" %s\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" </thead>\n"\
- u" <tbody>\n"\
- u" <tr>\n"\
- u" <td class=\"progdesc\">\n"\
- u" %s\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" <tr>\n"\
- u" <td class=\"progtime\">\n"\
- u" <b>"+_('Start')+u":</b> %s, \n"\
- u" <b>"+_('Stop')+u":</b> %s, \n"\
- u" <b>"+_('Runtime')+":</b> %smin\n"\
- u" </td>\n"\
- u" </td>\n"\
- u" </tbody>\n"\
- u" <tfoot>\n"\
- u" <tr>\n"\
- u" <td>\n"\
- u" <table width=\"100%%\"\n"\
- u" class=\"popupbuttons\"\n"\
- u" border=\"0\"\n"\
- u" cellpadding=\"0\"\n"\
- u" cellspacing=\"4\">\n"\
- u" <tbody>\n"\
- u" <tr>\n"\
- u" <td onclick=\"document.location='record.rpy?chan=%s&start=%s&action=add'\">\n"\
- u" "+_('Record')+u"\n"\
- u" </td>\n"\
- u" <td onclick=\"document.location='edit_favorite.rpy?chan=%s&start=%s&action=add'\">\n"\
- u" "+_('Add to Favorites')+u"\n"\
- u" </td>\n"\
- u" <td onclick=\"javascript:closePop('%s');\">\n"\
- u" "+_('Close Window')+"\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" </tbody>\n"\
- u" </table>\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" </tfoot>\n"\
- u" </table>\n"\
- u"</div>\n"
- ) % (
- popid, popid, popid, prog.title, desc,
- time.strftime('%H:%M',
- time.localtime( prog.start ) ),
- time.strftime('%H:%M',
- time.localtime( prog.stop ) ),
- int( ( prog.stop - prog.start ) / 60 ),
- prog.channel_id, prog.start,
- prog.channel_id, prog.start, popid
- )
- fv.tableCell(prog.title + ' - ' + prog.desc, 'class="'+status+'" onclick="showPop(\'%s\', this)" width="80%%"' % popid )
+ fv.tableCell(prog.title + ' - ' + prog.desc, 'class="'+status+'" onclick="guide_click(this, event)" id="%s" width="80%%"' % popid )
fv.tableCell(time.strftime('%H:%M', time.localtime(prog.start)), 'class="channel"')
fv.tableCell(time.strftime('%H:%M', time.localtime(prog.stop)), 'class="channel"')
fv.tableRowClose()
@@ -270,10 +200,58 @@
fv.tableCell('<center>'+_('NO SHOWS MATCHING CATEGORY')+'</center>', 'class="utilhead" colspan="4"')
fv.tableRowClose()
fv.tableClose()
- fv.res += pops
fv.printSearchForm()
fv.printLinks()
+ fv.res += (
+ u"<div id=\"popup\" class=\"proginfo\" style=\"display:none\">\n"\
+ u"<div id=\"program-waiting\" style=\"background-color: #0B1C52; position: absolute\">\n"\
+ u" <br /><b>Fetching program information ...</b>\n"\
+ u"</div>\n"\
+ u" <table id=\"program-info\" class=\"popup\">\n"\
+ u" <thead>\n"\
+ u" <tr>\n"\
+ u" <td id=\"program-title\">\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" </thead>\n"\
+ u" <tbody>\n"\
+ u" <tr>\n"\
+ u" <td class=\"progdesc\" id=\"program-desc\">\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" <tr>\n"\
+ u" <td class=\"progtime\">\n"\
+ u" <b>"+_('Start')+u":</b> <span id=\"program-start\"></span>, \n"\
+ u" <b>"+_('Stop')+u":</b> <span id=\"program-end\"></span>, \n"\
+ u" <b>"+_('Runtime')+u":</b> <span id=\"program-runtime\"></span> min\n"\
+ u" </td>\n"\
+ u" </td>\n"\
+ u" </tbody>\n"\
+ u" <tfoot>\n"\
+ u" <tr>\n"\
+ u" <td>\n"\
+ u" <table class=\"popupbuttons\">\n"\
+ u" <tbody>\n"\
+ u" <tr>\n"\
+ u" <td id=\"program-record-button\">\n"\
+ u" "+_('Record')+u"\n"\
+ u" </td>\n"\
+ u" <td id=\"program-favorites-button\">\n"\
+ u" "+_('Add to Favorites')+u"\n"\
+ u" </td>\n"\
+ u" <td onclick=\"program_popup_close();\">\n"\
+ u" "+_('Close Window')+u"\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" </tbody>\n"\
+ u" </table>\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" </tfoot>\n"\
+ u" </table>\n"\
+ u"</div>\n" )
+ fv.res += "<iframe id='hidden' style='visibility: hidden; width: 1px; height: 1px'></iframe>\n"
fv.printFooter()
return String( fv.res )
diff -Naur htdocs.old/guide.rpy htdocs/guide.rpy
--- htdocs.old/guide.rpy 2004-03-11 22:05:50.000000000 -0500
+++ htdocs/guide.rpy 2004-08-10 00:40:14.326868288 -0400
@@ -96,8 +96,6 @@
TRUE = 1
FALSE = 0
-MAX_DESCRIPTION_CHAR = 1000
-
class GuideResource(FreevoResource):
def makecategorybox(self, chanlist):
@@ -201,7 +199,6 @@
[ '<b>'+_('ERROR')+'</b>: '+_('Recording server is unavailable.') ]
)
- pops = ''
desc = ''
fv.tableOpen()
@@ -213,7 +210,7 @@
fv.tableRowClose()
fv.tableClose()
- fv.tableOpen('cols=\"%d\"' % \
+ fv.tableOpen('id="guide" cols=\"%d\"' % \
( n_cols*cpb + 1 ) )
showheader = 0
for chan in guide.chan_list:
@@ -241,14 +238,15 @@
fv.tableRowClose()
showheader+= 1
+ rowdata = []
now = mfrguidestart
- fv.tableRowOpen('class="chanrow"')
# chan.displayname = string.replace(chan.displayname, "&", "SUB")
- fv.tableCell(chan.displayname, 'class="channel"')
+ rowdata.append("<tr class='chanrow'>")
+ rowdata.append("<td class='channel'>%s</td>" % chan.displayname)
c_left = n_cols * cpb
if not chan.programs:
- fv.tableCell('« '+_('This channel has no data loaded')+' »', 'class="programnodata" colspan="%s"' % (n_cols* cpb) )
+ rowdata.append('<td class="programnodata" colspan="%s">« ' % (n_cols*cpb) + _('This channel has no data loaded') + ' »' )
for prog in chan.programs:
if prog.stop > mfrguidestart and \
@@ -286,96 +284,70 @@
colspan = c_left
popid = '%s:%s' % (prog.channel_id, prog.start)
- if prog.desc == '':
- desc = (_('Sorry, the program description for ' \
- '%s is unavailable.')) % ('<b>'+prog.title+'</b>')
- else:
- desc = prog.desc
-
- desc = desc.lstrip()
- if MAX_DESCRIPTION_CHAR and len(desc) > MAX_DESCRIPTION_CHAR:
- desc=desc[:desc[:MAX_DESCRIPTION_CHAR].rfind('.')] + '. [...]'
-
-
-
- if prog.sub_title:
- desc = '"%s"<br/>%s' % (prog.sub_title,desc)
-
-
- pops += (
- u"<div id=\"%s\" class=\"proginfo\">\n"\
- u" <table class=\"popup\"\n"\
- u" onmouseover=\"focusPop('%s');\"\n"\
- u" onmouseout=\"unfocusPop('%s');\">\n"\
- u" <thead>\n"\
- u" <tr>\n"\
- u" <td>\n"\
- u" %s\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" </thead>\n"\
- u" <tbody>\n"\
- u" <tr>\n"\
- u" <td class=\"progdesc\">\n"\
- u" %s\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" <tr>\n"\
- u" <td class=\"progtime\">\n"\
- u" <b>"+_('Start')+u":</b> %s, \n"\
- u" <b>"+_('Stop')+u":</b> %s, \n"\
- u" <b>"+_('Runtime')+u":</b> %smin\n"\
- u" </td>\n"\
- u" </td>\n"\
- u" </tbody>\n"\
- u" <tfoot>\n"\
- u" <tr>\n"\
- u" <td>\n"\
- u" <table class=\"popupbuttons\">\n"\
- u" <tbody>\n"\
- u" <tr>\n"\
- u" <td onclick=\"document.location='record.rpy?chan=%s&start=%s&action=add'\">\n"\
- u" "+_('Record')+u"\n"\
- u" </td>\n"\
- u" <td onclick=\"document.location='edit_favorite.rpy?chan=%s&start=%s&action=add'\">\n"\
- u" "+_('Add to Favorites')+u"\n"\
- u" </td>\n"\
- u" <td onclick=\"javascript:closePop('%s');\">\n"\
- u" "+_('Close Window')+u"\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" </tbody>\n"\
- u" </table>\n"\
- u" </td>\n"\
- u" </tr>\n"\
- u" </tfoot>\n"\
- u" </table>\n"\
- u"</div>\n"
- ) % ( popid, popid, popid, prog.title, desc,
- time.strftime(config.TV_TIMEFORMAT,
- time.localtime( prog.start ) ),
- time.strftime(config.TV_TIMEFORMAT,
- time.localtime( prog.stop ) ),
- int( ( prog.stop - prog.start ) / 60 ),
- prog.channel_id, prog.start,
- prog.channel_id, prog.start, popid )
-
style = ''
if colspan == n_cols * cpb:
style += 'text-align: center; '
-
- fv.tableCell(cell, 'class="'+status+'" onclick="showPop(\'%s\', this)" colspan="%s" style="%s"' % (popid, colspan, style))
+
+ rowdata.append('<td class="%s" onclick="guide_click(this, event)" id="%s" colspan="%s", style="%s">%s</td>' % (status, popid, colspan, style, cell))
now += colspan * PRECISION
c_left -= colspan
- fv.tableRowClose()
+ rowdata.append("</tr>")
+ fv.res += string.join(rowdata, "\n")
fv.tableClose()
- fv.res += pops
-
fv.printSearchForm()
fv.printLinks()
fv.res += '</div>'
+ fv.res += (
+ u"<div id=\"popup\" class=\"proginfo\" style=\"display:none\">\n"\
+ u"<div id=\"program-waiting\" style=\"background-color: #0B1C52; position: absolute\">\n"\
+ u" <br /><b>Fetching program information ...</b>\n"\
+ u"</div>\n"\
+ u" <table id=\"program-info\" class=\"popup\">\n"\
+ u" <thead>\n"\
+ u" <tr>\n"\
+ u" <td id=\"program-title\">\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" </thead>\n"\
+ u" <tbody>\n"\
+ u" <tr>\n"\
+ u" <td class=\"progdesc\" id=\"program-desc\">\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" <tr>\n"\
+ u" <td class=\"progtime\">\n"\
+ u" <b>"+_('Start')+u":</b> <span id=\"program-start\"></span>, \n"\
+ u" <b>"+_('Stop')+u":</b> <span id=\"program-end\"></span>, \n"\
+ u" <b>"+_('Runtime')+u":</b> <span id=\"program-runtime\"></span> min\n"\
+ u" </td>\n"\
+ u" </td>\n"\
+ u" </tbody>\n"\
+ u" <tfoot>\n"\
+ u" <tr>\n"\
+ u" <td>\n"\
+ u" <table class=\"popupbuttons\">\n"\
+ u" <tbody>\n"\
+ u" <tr>\n"\
+ u" <td id=\"program-record-button\">\n"\
+ u" "+_('Record')+u"\n"\
+ u" </td>\n"\
+ u" <td id=\"program-favorites-button\">\n"\
+ u" "+_('Add to Favorites')+u"\n"\
+ u" </td>\n"\
+ u" <td onclick=\"program_popup_close();\">\n"\
+ u" "+_('Close Window')+u"\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" </tbody>\n"\
+ u" </table>\n"\
+ u" </td>\n"\
+ u" </tr>\n"\
+ u" </tfoot>\n"\
+ u" </table>\n"\
+ u"</div>\n" )
+ fv.res += "<iframe id='hidden' style='visibility: hidden; width: 1px; height: 1px'></iframe>\n"
fv.printFooter()
return String( fv.res )
diff -Naur htdocs.old/proginfo.rpy htdocs/proginfo.rpy
--- htdocs.old/proginfo.rpy 1969-12-31 19:00:00.000000000 -0500
+++ htdocs/proginfo.rpy 2004-08-10 00:00:10.075370072 -0400
@@ -0,0 +1,103 @@
+#!/usr/bin/python
+
+#if 0 /*
+# -----------------------------------------------------------------------
+# proginfo.rpy - Dynamically update program info popup box.
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# ----------------------------------------------------------------------- */
+#endif
+
+import sys, string
+import time
+
+from www.web_types import HTMLResource, FreevoResource
+from twisted.web.woven import page
+
+import util.tv_util as tv_util
+import util
+import config
+import tv.epg_xmltv
+import tv.record_client as ri
+from twisted.web import static
+
+MAX_DESCRIPTION_CHAR = 1000
+
+class ProgInfoResource(FreevoResource):
+
+ def _render(self, request):
+ fv = HTMLResource()
+ form = request.args
+ id = fv.formValue(form, 'id')
+ chanid = id[:id.find(":")]
+ starttime = int( id[id.find(":")+1:] )
+
+ t0=time.time()
+ guide = tv.epg_xmltv.get_guide()
+ t1=time.time()
+ (got_schedule, schedule) = ri.getScheduledRecordings()
+ if got_schedule:
+ schedule = schedule.getProgramList()
+
+ chan = guide.chan_dict[chanid]
+ for prog in chan.programs:
+ if prog.start == starttime:
+ break
+
+ if prog.desc == '':
+ desc = (_('Sorry, the program description for ' \
+ '%s is unavailable.')) % ('<b>'+prog.title+'</b>')
+ else:
+ desc = prog.desc
+
+ desc = desc.lstrip()
+ if MAX_DESCRIPTION_CHAR and len(desc) > MAX_DESCRIPTION_CHAR:
+ desc=desc[:desc[:MAX_DESCRIPTION_CHAR].rfind('.')] + '. [...]'
+
+ if prog.sub_title:
+ desc = '"%s"<br/>%s' % (prog.sub_title,desc)
+
+ fv.res += (
+ u"<script>\n" \
+ u"var doc = parent.top.document;\n" \
+ u"doc.getElementById('program-title').innerHTML = '%s';\n"\
+ u"doc.getElementById('program-desc').innerHTML = '%s';\n"\
+ u"doc.getElementById('program-start').innerHTML = '%s';\n"
+ u"doc.getElementById('program-end').innerHTML = '%s';\n"\
+ u"doc.getElementById('program-runtime').innerHTML = '%s';\n"\
+ u"doc.getElementById('program-record-button').onclick = %s;\n"\
+ u"doc.getElementById('program-favorites-button').onclick = %s;\n"\
+ u"doc.getElementById('program-waiting').style.display = 'none';\n" \
+ u"doc.getElementById('program-info').style.visibility = 'visible';\n" \
+ u"</script>\n"
+ ) % ( prog.title.replace("'", "\\'") , desc.replace("'", "\\'"),
+ time.strftime(config.TV_TIMEFORMAT,
+ time.localtime( prog.start ) ),
+ time.strftime(config.TV_TIMEFORMAT,
+ time.localtime( prog.stop ) ),
+ int( ( prog.stop - prog.start ) / 60 ),
+ "function() { doc.location=\"record.rpy?chan=%s&start=%s&action=add\"; }" % (chanid, starttime),
+ "function() { doc.location=\"edit_favorite.rpy?chan=%s&start=%s&action=add\"; }" % (chanid, starttime),
+
+ )
+
+ return String( fv.res )
+
+resource = ProgInfoResource()
diff -Naur htdocs.old/scripts/display_prog-head.js htdocs/scripts/display_prog-head.js
--- htdocs.old/scripts/display_prog-head.js 2004-02-15 23:23:54.000000000 -0500
+++ htdocs/scripts/display_prog-head.js 2004-08-10 00:37:08.819069760 -0400
@@ -5,29 +5,46 @@
N = (document.all) ? 0 : 1;
-function focusPop(pop) {
- popid = pop;
- over = true;
-}
-
-function unfocusPop(pop) {
- popid = '';
- over = false;
-}
-
-function showPop(pop, cell) {
- pop = document.getElementById(pop);
- pop.style.top = (popY-100) + "px";
- pop.style.visibility = 'visible';
-}
-
-function closePop(pop) {
- pop = document.getElementById(pop);
- pop.style.visibility = 'hidden';
+function
+guide_click(item, event)
+{
+ var iframe = document.getElementById("hidden");
+ iframe.src="proginfo.rpy?id=" + item.id;
+ document.getElementById("program-waiting").style.display = "";
+ document.getElementById("program-info").style.visibility = "hidden";
+ var popup = document.getElementById("popup");
+ popup.style.display = "";
+
+ w = N ? window.innerWidth : document.body.clientWidth;
+ h = N ? window.innerHeight : document.body.clientHeight;
+
+ //alert(event.clientX + " " + popup.clientWidth + " " + w + " " + h);
+ if (event.clientX + popup.clientWidth > w)
+ x = (w - popup.clientWidth) - 30;
+ else
+ x = event.clientX;
+ popup.style.left = x + "px";
+
+ page_top = N ? window.pageYOffset : document.body.scrollTop;
+
+ // We can't use popup.clientHeight because it's not valud until
+ // after proginfo.rpy gets executed, so we guess that it'll be
+ // about 175. Someone else can fix this. :)
+ if (event.clientY + 175 > h)
+ y = page_top + (h - 175) - 20;
+ else
+ y = page_top + event.clientY;
+ popup.style.top = y + "px";
+}
+
+function
+program_popup_close()
+{
+ var popup = document.getElementById("popup");
+ popup.style.display = "none";
}
function mouseDown(e) {
- popY = (N) ? e.pageY : event.y+document.body.scrollTop;
if(over) {
if(N) {
ob = document.getElementById(popid);
diff -Naur htdocs.old/styles/main.css htdocs/styles/main.css
--- htdocs.old/styles/main.css 2004-02-12 09:04:37.000000000 -0500
+++ htdocs/styles/main.css 2004-08-10 00:41:48.311580440 -0400
@@ -222,11 +222,10 @@
.proginfo {
width: 450px;
position: absolute;
- left: 250px;
- top: 200px;
+ background: #0B1C52;
+ color: white;
font-size: 13px;
font-family: "Trebuchet MS", Helvetica, Verdana, sans-serif;
- visibility: hidden;
border: #000 3px solid;
}
signature.asc
Description: This is a digitally signed message part
