diff -r 058bb3dc685f -r 0b59724cb3f2 cubicweb/web/htmlwidgets.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/htmlwidgets.py Sat Jan 16 13:48:51 2016 +0100 @@ -0,0 +1,367 @@ +# copyright 2003-2010 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 . +"""html widgets + +those are in cubicweb since we need to know available widgets at schema +serialization time +""" + +import random +from math import floor + +from six import add_metaclass +from six.moves import range + +from logilab.mtconverter import xml_escape +from logilab.common.deprecation import class_deprecated + +from cubicweb.utils import UStringIO +from cubicweb.uilib import toggle_action, htmlescape +from cubicweb.web import jsonize +from cubicweb.web.component import _bwcompatible_render_item + +# XXX HTMLWidgets should have access to req (for datadir / static urls, +# i18n strings, etc.) +class HTMLWidget(object): + + def _initialize_stream(self, w=None): + if w: + self.w = w + else: + self._stream = UStringIO() + self.w = self._stream.write + + def _render(self): + raise NotImplementedError + + def render(self, w=None): + self._initialize_stream(w) + self._render() + if w is None: + return self._stream.getvalue() + + def is_empty(self): + return False + + +class BoxWidget(HTMLWidget): # XXX Deprecated + + def __init__(self, title, id, items=None, _class="boxFrame", + islist=True, shadow=True, escape=True): + self.title = title + self.id = id + self.items = items or [] + self._class = _class + self.islist = islist + self.shadow = shadow + self.escape = escape + + def __len__(self): + return len(self.items) + + def is_empty(self): + return len(self) == 0 + + def append(self, item): + self.items.append(item) + + def extend(self, items): + self.items.extend(items) + + title_class = 'boxTitle' + main_div_class = 'boxContent' + listing_class = 'boxListing' + + def box_begin_content(self): + self.w(u'
\n' % self.main_div_class) + if self.islist: + self.w(u'\n') + self.w(u'
\n') + if self.shadow: + self.w(u'
 
') + + def _render(self): + if self.id: + self.w(u'
' % (self._class, self.id)) + else: + self.w(u'
' % self._class) + if self.title: + if self.escape: + title = '%s' % xml_escape(self.title) + else: + title = '%s' % self.title + self.w(u'
%s
' % (self.title_class, title)) + if self.items: + self.box_begin_content() + for item in self.items: + _bwcompatible_render_item(self.w, item) + self.box_end_content() + self.w(u'
') + + +@add_metaclass(class_deprecated) +class SideBoxWidget(BoxWidget): + """default CubicWeb's sidebox widget""" + __deprecation_warning__ = '[3.10] class %(cls)s is deprecated' + + title_class = u'sideBoxTitle' + main_div_class = u'sideBoxBody' + listing_class = '' + + def __init__(self, title, id=None): + super(SideBoxWidget, self).__init__(title, id=id, _class='sideBox', + shadow=False) + + +class MenuWidget(BoxWidget): + + main_div_class = 'menuContent' + listing_class = 'menuListing' + + def box_end_content(self): + if self.islist: + self.w(u'\n') + self.w(u'
\n') + + +class RawBoxItem(HTMLWidget): # XXX deprecated + """a simple box item displaying raw data""" + + def __init__(self, label, liclass=None): + self.label = label + self.liclass = liclass + + def _start_li(self): + if self.liclass is None: + return u'
  • ' + else: + return u'
  • ' % self.liclass + + def _render(self): + self.w(u'%s%s
  • ' % (self._start_li(), self.label)) + + +class BoxMenu(RawBoxItem): + """a menu in a box""" + + link_class = 'boxMenu' + + def __init__(self, label, items=None, isitem=True, liclass=None, ident=None, + link_class=None): + super(BoxMenu, self).__init__(label, liclass) + self.items = items or [] + self.isitem = isitem + self.ident = ident or u'boxmenu_%s' % label.replace(' ', '_').replace("'", '') + if link_class: + self.link_class = link_class + + def append(self, item): + self.items.append(item) + + def _begin_menu(self, ident): + self.w(u'') + + def _render(self): + if self.isitem: + self.w(self._start_li()) + ident = self.ident + self.w(u'%s' % ( + toggle_action(ident), self.link_class, self.label)) + self._begin_menu(ident) + for item in self.items: + _bwcompatible_render_item(self.w, item) + self._end_menu() + if self.isitem: + self.w(u'') + + +class PopupBoxMenu(BoxMenu): + """like BoxMenu but uses div and specific css class + in order to behave like a popup menu + """ + link_class = 'popupMenu' + + def _begin_menu(self, ident): + self.w(u'
    ') + + +@add_metaclass(class_deprecated) +class BoxField(HTMLWidget): + """couples label / value meant to be displayed in a box""" + __deprecation_warning__ = '[3.10] class %(cls)s is deprecated' + def __init__(self, label, value): + self.label = label + self.value = value + + def _render(self): + self.w(u'
  • %s ' + u'%s
  • ' + % (self.label, self.value)) + + +@add_metaclass(class_deprecated) +class BoxSeparator(HTMLWidget): + """a menu separator""" + __deprecation_warning__ = '[3.10] class %(cls)s is deprecated' + + def _render(self): + self.w(u'