13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
14 # details. |
14 # details. |
15 # |
15 # |
16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
18 """abstract component class and base components definition for CubicWeb web client |
18 """abstract component class and base components definition for CubicWeb web |
19 |
19 client |
20 """ |
20 """ |
|
21 |
21 __docformat__ = "restructuredtext en" |
22 __docformat__ = "restructuredtext en" |
22 _ = unicode |
23 _ = unicode |
23 |
24 |
24 from logilab.common.deprecation import class_renamed |
25 from logilab.common.deprecation import class_renamed |
25 from logilab.mtconverter import xml_escape |
26 from logilab.mtconverter import xml_escape |
26 |
27 |
27 from cubicweb import role |
28 from cubicweb import role |
28 from cubicweb.web import json |
29 from cubicweb.utils import json_dumps |
|
30 from cubicweb.uilib import js |
29 from cubicweb.view import Component |
31 from cubicweb.view import Component |
30 from cubicweb.selectors import ( |
32 from cubicweb.selectors import ( |
31 paginated_rset, one_line_rset, primary_view, match_context_prop, |
33 paginated_rset, one_line_rset, primary_view, match_context_prop, |
32 partial_has_related_entities) |
34 partial_has_related_entities) |
33 |
35 |
59 } |
61 } |
60 |
62 |
61 context = 'navcontentbottom' |
63 context = 'navcontentbottom' |
62 |
64 |
63 def call(self, view=None): |
65 def call(self, view=None): |
64 return self.cell_call(0, 0, view=view) |
66 if self.cw_rset is None: |
|
67 self.entity_call(self.cw_extra_kwargs.pop('entity')) |
|
68 else: |
|
69 self.cell_call(0, 0, view=view) |
65 |
70 |
66 def cell_call(self, row, col, view=None): |
71 def cell_call(self, row, col, view=None): |
|
72 self.entity_call(self.cw_rset.get_entity(row, col), view=view) |
|
73 |
|
74 def entity_call(self, entity, view=None): |
67 raise NotImplementedError() |
75 raise NotImplementedError() |
68 |
76 |
69 |
77 |
70 class NavigationComponent(Component): |
78 class NavigationComponent(Component): |
71 """abstract base class for navigation components""" |
79 """abstract base class for navigation components""" |
124 if self.start_param in params: |
132 if self.start_param in params: |
125 del params[self.start_param] |
133 del params[self.start_param] |
126 if self.stop_param in params: |
134 if self.stop_param in params: |
127 del params[self.stop_param] |
135 del params[self.stop_param] |
128 |
136 |
129 def page_url(self, path, params, start, stop): |
137 def page_url(self, path, params, start=None, stop=None): |
130 params = dict(params) |
138 params = dict(params) |
131 params.update({self.start_param : start, |
139 if start is not None: |
132 self.stop_param : stop,}) |
140 params[self.start_param] = start |
|
141 if stop is not None: |
|
142 params[self.stop_param] = stop |
133 view = self.cw_extra_kwargs.get('view') |
143 view = self.cw_extra_kwargs.get('view') |
134 if view is not None and hasattr(view, 'page_navigation_url'): |
144 if view is not None and hasattr(view, 'page_navigation_url'): |
135 url = view.page_navigation_url(self, path, params) |
145 url = view.page_navigation_url(self, path, params) |
136 elif path == 'json': |
146 elif path == 'json': |
137 rql = params.pop('rql', self.cw_rset.printable_rql()) |
147 url = self.ajax_page_url(**params) |
138 # latest 'true' used for 'swap' mode |
|
139 url = 'javascript: replacePageChunk(%s, %s, %s, %s, true)' % ( |
|
140 json.dumps(params.get('divid', 'pageContent')), |
|
141 json.dumps(rql), json.dumps(params.pop('vid', None)), json.dumps(params)) |
|
142 else: |
148 else: |
143 url = self._cw.build_url(path, **params) |
149 url = self._cw.build_url(path, **params) |
|
150 # XXX hack to avoid opening a new page containing the evaluation of the |
|
151 # js expression on ajax call |
|
152 if url.startswith('javascript:'): |
|
153 url += '; noop();' |
144 return url |
154 return url |
|
155 |
|
156 def ajax_page_url(self, **params): |
|
157 divid = params.setdefault('divid', 'pageContent') |
|
158 params['rql'] = self.cw_rset.printable_rql() |
|
159 return "javascript: $(%s).loadxhtml('json', %s, 'get', 'swap')" % ( |
|
160 json_dumps('#'+divid), js.ajaxFuncArgs('view', params)) |
145 |
161 |
146 def page_link(self, path, params, start, stop, content): |
162 def page_link(self, path, params, start, stop, content): |
147 url = xml_escape(self.page_url(path, params, start, stop)) |
163 url = xml_escape(self.page_url(path, params, start, stop)) |
148 if start == self.starting_from: |
164 if start == self.starting_from: |
149 return self.selected_page_link_templ % (url, content, content) |
165 return self.selected_page_link_templ % (url, content, content) |