From 9da21cb347352e45013de7a3fed3abeba03c3349 Mon Sep 17 00:00:00 2001 From: tonio Date: Fri, 19 Feb 2010 18:17:19 +0100 Subject: [PATCH] Pure CSS layout working with FF. (at least for the webmail) Trying to make it work with IE6+... --- extensions/webmail/imap_listing.py | 6 +- extensions/webmail/templates/index.html | 48 +++++++-- lib/email_listing.py | 10 +- lib/tables.py | 41 ++++++-- static/js/common.js | 13 ++- static/stylesheets/default.css | 56 +++++++--- templates/common/email_listing.html | 19 +++- templates/common/table_body.html | 13 +++ templates/common/table_head.html | 10 ++ templates/common/tables.html | 1 + templates/nlayout.html | 132 +++++++++++------------- 11 files changed, 233 insertions(+), 116 deletions(-) create mode 100644 templates/common/table_body.html create mode 100644 templates/common/table_head.html diff --git a/extensions/webmail/imap_listing.py b/extensions/webmail/imap_listing.py index 310017911..8656cda15 100644 --- a/extensions/webmail/imap_listing.py +++ b/extensions/webmail/imap_listing.py @@ -17,11 +17,11 @@ class WMtable(tables.Table): tableid = "emails" idkey = "imapid" # selection = tables.SelectionColumn("selection", width="20px", first=True) - _1_flags = tables.ImgColumn("flags", width="5%") + _1_flags = tables.ImgColumn("flags", width="6%") _2_subject = tables.Column("subject", label=_("Subject"), - cssclass="draggable") + cssclass="draggable", width="50%") _3_from_ = tables.Column("from", width="20%", label=_("From")) - _4_date = tables.Column("date", width="10%", label=_("Date")) + _4_date = tables.Column("date", width="20%", label=_("Date")) def parse(self, header, value): diff --git a/extensions/webmail/templates/index.html b/extensions/webmail/templates/index.html index c55de985e..9417c65a6 100644 --- a/extensions/webmail/templates/index.html +++ b/extensions/webmail/templates/index.html @@ -6,6 +6,30 @@ width: 150px; } +thead tr { + position: relative; + top: expression(offsetParent.scrollTop); /*IE5+ only*/ + z-index: 1; +} + +table#emails > tbody { + position: fixed; + bottom: 35px; + top: 155px; + left: 155px; + right: 0px; + overflow-x: hidden; + overflow-y: auto; +} + +#emails th { + text-align: center; +} + +#emails tr { + width: 100%; +} + .box h3 { font-size: small; margin: 2px 0px 2px 0px; @@ -78,21 +102,22 @@ tr { }); updatelisting = function(resp, overflow) { - if (!$defined(overflow)) { + /*if (!$defined(overflow)) { overflow = "auto"; - } + }*/ if ($defined(resp.menu)) { $("menubar").set("html", resp.menu); } $("listing").set("html", resp.listing); - $("listing").setStyle("overflow", overflow); - if ($defined(resp.navbar)) { + /*if ($defined(resp.navbar)) { $("navbar").set("html", resp.navbar); + $("navbar").setStyle("display", "block"); $("navbar").getChildren("a").addEvent("click", navbarcallback); - } + }*/ $$("a[name=compose]").addEvent("click", loadCompose); $$("a[name=empty]").addEvent("click", empty); } + empty = function(event) { event.stop(); new Request.JSON({url : event.target.get("href"), onSuccess : function(resp) { @@ -169,7 +194,7 @@ tr { th.getElement("img").set("src", "/static/pics/" + src); th.addClass("selected"); } - $$("td[class*=draggable]").each(function(item) { + /*$$("td[class*=draggable]").each(function(item) { item.makeDraggable({ droppables: ".droppable", }).addEvents({ @@ -215,7 +240,7 @@ tr { } } }); - }); + });*/ $$("tr").addEvent("dblclick", viewmail); $$("th[class*=sortable]").addEvent("click", function(evt) { var tmp = "?"; @@ -235,20 +260,21 @@ tr { }); }); - navbarcallback = function(event) { + /*navbarcallback = function(event) { event.stop(); current_anchor.setparams(navparams); current_anchor.parse_string(event.target.getParent().get("href")).update(); - } + }*/ foldercallback = function(event) { select(event.target); loadFolder(event, event.target); } - ajaxListener("INBOX", updatelisting); + ajaxListener("INBOX/", updatelisting); $$("a[name=loadfolder]").addEvent("click", foldercallback); - $("navbar").getChildren("a").addEvent("click", navbarcallback); + /*$("navbar").getChildren("a").addEvent("click", navbarcallback);*/ + {% endblock %} {% block middletitle %}{% trans "Webmail" %}{% endblock %} {% block leftcol %} diff --git a/lib/email_listing.py b/lib/email_listing.py index a2d36e11d..c6c827fab 100644 --- a/lib/email_listing.py +++ b/lib/email_listing.py @@ -94,25 +94,25 @@ class EmailListing: def fetch(self, request, id_start, id_stop): table = self.tbltype(self.mbc.fetch(start=id_start, stop=id_stop, - folder=self.folder)).render(request) + folder=self.folder)) tpl = Template("""
{{ table }}
""") - return tpl.render(Context({"table" : table})) + return tpl.render(Context({"table" : table.render(request)})) def render(self, request, pageid=1, **kwargs): page = self.paginator.getpage(pageid) + thead = listing = "" if "empty" in kwargs.keys() and not kwargs["empty"]: if not page: listing = "Empty folder" else: listing = self.fetch(request, page.id_start, page.id_stop) - else: - listing = "" elapsed = kwargs.has_key("start") and time.time() - kwargs["start"] or 0 return _render(request, self.tpl, { - "listing" : listing, "elapsed" : elapsed, + "listing" : listing, + "elapsed" : elapsed, "navbar" : self.render_navbar(page), "folders" : self.getfolders(), "selection" : self.folder, diff --git a/lib/tables.py b/lib/tables.py index 8ec897eeb..938df9cad 100644 --- a/lib/tables.py +++ b/lib/tables.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import inspect import lxml +from django.template import Template, Context from django.template.loader import render_to_string class Column: @@ -53,9 +54,9 @@ class Table(object): if isinstance(c, ImgColumn): key = "img_%s" % c.name if key in row.keys(): - nrow["cols"] += [{"value" : c.render(row[key]), "safe" : True}] + nrow["cols"] += [{"value" : c.render(row[key]), "safe" : True, "width" : c.width}] else: - nrow["cols"] += ["."] + nrow["cols"] += [{"width" : c.width}] continue if row.has_key(c.name): try: @@ -66,10 +67,38 @@ class Table(object): cssclass += (cssclass != "") and ", %s" % row["class"] or row["class"] nrow["cols"] += [{"value" : self.parse(c.name, row[c.name]), - "class" : cssclass}] + "class" : cssclass, + "width" : c.width}] self.rows += [nrow] def render(self, request): - return render_to_string("common/tables.html", { - "table" : self, "tableid" : self.tableid - }) + t = Template(""" + + {% include "common/table_head.html" %} + {% include "common/table_body.html" %} +
+""") + return t.render(Context({ + "table" : self, "tableid" : self.tableid + })) + + def render_head(self, request): + t = Template(""" + + {% include "common/table_head.html" %} +
+""") + return t.render(Context({ + "table" : self, "tableid" : "%s_head" % self.tableid + })) + + def render_body(self, request): + t = Template(""" + + {% include "common/table_body.html" %} +
+""") + return t.render(Context({ + "table" : self, "tableid" : "%s_body" % self.tableid + })) + diff --git a/static/js/common.js b/static/js/common.js index d2bd80afb..b859c883a 100644 --- a/static/js/common.js +++ b/static/js/common.js @@ -1,9 +1,9 @@ window.addEvent('domready', function(){ parse_menubar('topmenubar'); parse_menubar('menubar'); - SqueezeBox.assign($$('a.boxed'), { + /*SqueezeBox.assign($$('a.boxed'), { parse: 'rel', - }); + });*/ }); callbacks = {}; @@ -15,10 +15,10 @@ register_callback = function(name, callback) { current_anchor = null; check_anchor = function() { - if (current_anchor.serialized == document.location.hash) { + if (current_anchor.serialized == location.hash) { return; } - current_anchor.from_string(document.location.hash); + current_anchor.from_string(location.hash); if (!current_anchor.serialized) { query = current_anchor.deflocation; } else { @@ -134,7 +134,7 @@ function HashWrapper(deflocation) { parse_menubar = function(id) { if ($(id)) { - $(id).getElements('li.dropdown').each( function( elem ){ + $(id).getElements('li.dropdown').each(function( elem ){ var list = elem.getElement('ul.links'); var myFx = new Fx.Slide(list).hide(); elem.addEvents({ @@ -206,6 +206,9 @@ setDivHeight = function(id, extrah, modulo) { if ($("navbar")) { contentsize -= $("navbar").getSize().y; } + if ($("thead")) { + contentsize -= $("thead").getSize().y; + } if (modulo) { contentsize -= contentsize % modulo; } diff --git a/static/stylesheets/default.css b/static/stylesheets/default.css index 471cd3109..008f1f96e 100644 --- a/static/stylesheets/default.css +++ b/static/stylesheets/default.css @@ -5,15 +5,35 @@ html, body { margin: 0; padding: 0; height: 100%; + overflow: hidden; } -#topmenubar { - width: 100%; - margin: 0 auto; - padding: 0; - background: #072342; - border-bottom: 2px solid #333; +div#container { + height: auto !important; + height: 100%; + min-height: 100%; + position: relative; + background: white; +} + +@media screen { + body > div#footer { + position: fixed; + } +} + +div#topmenubar { + position: fixed; + border-bottom: 5px solid #333; height: 30px; + bottom: auto; +} + +div#footer { + position: absolute; + height: 30px; + bottom: 0px; + border-top: 5px solid #333; } #menubar { @@ -45,14 +65,19 @@ html, body { } #page { - border: 2px solid #333; - background: white; - margin: 0 15px; + width: 100%; + top: 35px; + bottom: 35px; + position: absolute; } #content { + position: fixed; overflow: auto; padding: 5px; + top: 130px; + bottom: 35px; + width: 100%; } #header { @@ -101,6 +126,13 @@ html, body { width: 300px; } +.uibar { + background: #153F65; + padding: 0; + margin: 0 auto; + width: 100%; +} + .menubar a, .menubar a:visited { text-decoration: none; } @@ -138,7 +170,7 @@ html, body { } .left { - text-align: left; + float: left; } .right { @@ -198,12 +230,12 @@ html, body { } table { - margin: 0 auto; + /*margin: 0 auto;*/ width: 100%; border-collapse: collapse; - /*border-spacing: 20px;*/ } + tr.odd { background: white; } diff --git a/templates/common/email_listing.html b/templates/common/email_listing.html index 9c9e3c569..959388161 100644 --- a/templates/common/email_listing.html +++ b/templates/common/email_listing.html @@ -3,18 +3,28 @@ {% block html_head %}