--- a/web/views/tabs.py Mon Jan 04 18:40:30 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""base classes to handle tabbed views"""
-
-__docformat__ = "restructuredtext en"
-from cubicweb import _
-
-from six import string_types
-
-from logilab.common.deprecation import class_renamed
-from logilab.mtconverter import xml_escape
-
-from cubicweb import NoSelectableObject, role
-from cubicweb import tags, uilib, utils
-from cubicweb.predicates import partial_has_related_entities
-from cubicweb.view import EntityView
-from cubicweb.web.views import primary
-
-class LazyViewMixin(object):
- """provides two convenience methods for the tab machinery.
-
- Can also be used to lazy-load arbitrary views.
- """
-
- def _prepare_bindings(self, vid, reloadable):
- self._cw.add_onload(u"""
- jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) {
- loadNow('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s);
- });""" % {'event': 'load_%s' % vid, 'vid': vid,
- 'reloadable' : str(reloadable).lower()})
-
- def lazyview(self, vid, rql=None, eid=None, rset=None, tabid=None,
- reloadable=False, show_spinbox=True, w=None):
- """a lazy version of wview"""
- w = w or self.w
- self._cw.add_js('cubicweb.ajax.js')
- # the form is copied into urlparams to please the inner views
- # that might want to take params from it
- # beware of already present rql or eid elements
- # to be safe of collision a proper argument passing protocol
- # (with namespaces) should be used instead of the current
- # ad-hockery
- urlparams = self._cw.form.copy()
- urlparams.pop('rql', None)
- urlparams.pop('eid', None)
- urlparams.update({'vid' : vid, 'fname' : 'view'})
- if rql:
- urlparams['rql'] = rql
- elif eid:
- urlparams['eid'] = eid
- elif rset:
- urlparams['rql'] = rset.printable_rql()
- if tabid is None:
- tabid = uilib.domid(vid)
- w(u'<div id="lazy-%s" cubicweb:loadurl="%s">' % (
- tabid, xml_escape(self._cw.build_url('ajax', **urlparams))))
- if show_spinbox:
- # Don't use ``alt`` since image is a *visual* helper for ajax
- w(u'<img style="display: none" src="%s" alt="" id="%s-hole"/>'
- % (xml_escape(self._cw.data_url('loading.gif')), tabid))
- else:
- w(u'<div id="%s-hole"></div>' % tabid)
- w(u'<noscript><p>%s <a id="seo-%s" href="%s">%s</a></p></noscript>'
- % (xml_escape(self._cw._('Link:')),
- tabid,
- xml_escape(self._cw.build_url(**urlparams)),
- xml_escape(self._cw._(tabid))))
- w(u'</div>')
- self._prepare_bindings(tabid, reloadable)
-
- def forceview(self, vid):
- """trigger an event that will force immediate loading of the view on dom
- readyness
- """
- self._cw.add_onload(uilib.js.triggerLoad(vid))
-
-
-class TabsMixin(LazyViewMixin):
- """a tab mixin to easily get jQuery based, lazy, ajax tabs"""
- lazy = True
-
- @property
- def cookie_name(self):
- return str('%s_active_tab' % self._cw.vreg.config.appid)
-
- def active_tab(self, default):
- if 'tab' in self._cw.form:
- return self._cw.form['tab']
- cookies = self._cw.get_cookie()
- cookiename = self.cookie_name
- activetab = cookies.get(cookiename)
- if activetab is None:
- domid = uilib.domid(default)
- self._cw.set_cookie(cookiename, domid)
- return domid
- return activetab.value
-
- def prune_tabs(self, tabs, default_tab):
- selected_tabs = []
- may_be_active_tab = self.active_tab(default_tab)
- active_tab = uilib.domid(default_tab)
- viewsvreg = self._cw.vreg['views']
- for tab in tabs:
- if isinstance(tab, string_types):
- tabid, tabkwargs = tab, {}
- else:
- tabid, tabkwargs = tab
- tabkwargs = tabkwargs.copy()
- tabkwargs.setdefault('rset', self.cw_rset)
- vid = tabkwargs.get('vid', tabid)
- domid = uilib.domid(tabid)
- try:
- viewsvreg.select(vid, self._cw, tabid=domid, **tabkwargs)
- except NoSelectableObject:
- continue
- selected_tabs.append((tabid, domid, tabkwargs))
- if domid == may_be_active_tab:
- active_tab = domid
- return selected_tabs, active_tab
-
- def render_tabs(self, tabs, default, entity=None):
- # delegate to the default tab if there is more than one entity
- # in the result set (tabs are pretty useless there)
- if entity and len(self.cw_rset) > 1:
- entity.view(default, w=self.w)
- return
- self._cw.add_css('jquery.ui.css')
- self._cw.add_js(('jquery.ui.js', 'cubicweb.ajax.js', 'jquery.cookie.js'))
- # prune tabs : not all are to be shown
- tabs, active_tab = self.prune_tabs(tabs, default)
- # build the html structure
- w = self.w
- uid = entity and entity.eid or utils.make_uid('tab')
- w(u'<div id="entity-tabs-%s">' % uid)
- w(u'<ul>')
- active_tab_idx = None
- for i, (tabid, domid, tabkwargs) in enumerate(tabs):
- w(u'<li>')
- w(u'<a href="#%s">' % domid)
- w(tabkwargs.pop('label', self._cw._(tabid)))
- w(u'</a>')
- w(u'</li>')
- if domid == active_tab:
- active_tab_idx = i
- w(u'</ul>')
- for tabid, domid, tabkwargs in tabs:
- w(u'<div id="%s">' % domid)
- if self.lazy:
- tabkwargs.setdefault('tabid', domid)
- tabkwargs.setdefault('vid', tabid)
- self.lazyview(**tabkwargs)
- else:
- self._cw.view(tabid, w=self.w, **tabkwargs)
- w(u'</div>')
- w(u'</div>')
- # call the setTab() JS function *after* each tab is generated
- # because the callback binding needs to be done before
- # XXX make work history: true
- if self.lazy:
- self._cw.add_onload(u"""
- jQuery('#entity-tabs-%(uid)s').tabs(
- { active: %(tabindex)s,
- activate: function(event, ui) {
- setTab(ui.newPanel.attr('id'), '%(cookiename)s');
- }
- });
- setTab('%(domid)s', '%(cookiename)s');
-""" % {'tabindex' : active_tab_idx,
- 'domid' : active_tab,
- 'uid' : uid,
- 'cookiename' : self.cookie_name})
- else:
- self._cw.add_onload(
- u"jQuery('#entity-tabs-%(uid)s').tabs({active: %(tabindex)s});"
- % {'tabindex': active_tab_idx, 'uid': uid})
-
-
-class EntityRelationView(EntityView):
- """view displaying entity related stuff.
- Such a view _must_ provide the rtype, target and vid attributes :
-
- Example :
-
- class ProjectScreenshotsView(EntityRelationView):
- '''display project's screenshots'''
- __regid__ = title = _('projectscreenshots')
- __select__ = EntityRelationView.__select__ & is_instance('Project')
- rtype = 'screenshot'
- role = 'subject'
- vid = 'gallery'
-
- in this example, entities related to project entity by the 'screenshot'
- relation (where the project is subject of the relation) will be displayed
- using the 'gallery' view.
- """
- __select__ = EntityView.__select__ & partial_has_related_entities()
- vid = 'list'
- # to be defined in concrete classes
- rtype = title = None
-
- def cell_call(self, row, col):
- rset = self.cw_rset.get_entity(row, col).related(self.rtype, role(self))
- self.w(u'<div class="mainInfo">')
- if self.title:
- self.w(tags.h1(self._cw._(self.title)))
- self.wview(self.vid, rset, 'noresult')
- self.w(u'</div>')
-
-
-class TabbedPrimaryView(TabsMixin, primary.PrimaryView):
- __abstract__ = True # don't register
-
- tabs = [_('main_tab')]
- default_tab = 'main_tab'
-
- def render_entity(self, entity):
- self.render_entity_toolbox(entity)
- self.w(u'<div class="tabbedprimary"></div>')
- self.render_entity_title(entity)
- self.render_tabs(self.tabs, self.default_tab, entity)
-
-TabedPrimaryView = class_renamed('TabedPrimaryView', TabbedPrimaryView)
-
-class PrimaryTab(primary.PrimaryView):
- __regid__ = 'main_tab'
- title = None # should not appear in possible views
-
- def is_primary(self):
- return True
-
- def render_entity_title(self, entity):
- pass
- def render_entity_toolbox(self, entity):
- pass