def test_AjaxEvent(self): target = 'http://example.com' eventname = 'contextchanged' selector = '.contextsensitiv' event = AjaxEvent(target, eventname, selector) self.assertEqual((event.name, event.selector, event.target), (eventname, selector, target))
def render(self): request = self.request request.response.headers = forget(request) location = request.params.get('came_from', request.application_url) ajax_continue( self.request, AjaxEvent(target=location, name='contextchanged', selector='#layout')) return u''
def do_transition(self): """if ``do_transition`` is found on request.params, perform transition. """ transition = self.request.params.get('do_transition') if not transition: return workflow = self.workflow workflow.transition(self.model, self.request, transition) self.model() url = make_url(self.request, node=self.model) continuation = [AjaxEvent(url, 'contextchanged', '#layout')] self.request.environ['cone.app.continuation'] = continuation
def next(self, request): url = 'http://example.com' return [ AjaxAction(url, 'content', 'inner', '#content'), AjaxEvent(url, 'contextchanged', '.contextsensitiv') ]
def test_AjaxFormContinue(self): # AjaxFormContinue object. This object is used by ``render_ajax_form`` result = '' continuation = [] afc = AjaxFormContinue(result, continuation) self.assertEqual(afc.form, '') self.assertEqual(afc.next, 'false') # If no continuation definitions, ``form`` returns result and ``next`` # returns 'false' result = 'rendered form' afc = AjaxFormContinue(result, []) self.assertEqual(afc.form, 'rendered form') self.assertEqual(afc.next, 'false') # If continuation definitions and result, ``form`` returns empty # string, because form processing was successful. ``next`` returns a # JSON dump of given actions, which gets interpreted and executed on # client side action = AjaxAction( 'http://example.com', 'tilename', 'replace', '.someselector' ) event = AjaxEvent( 'http://example.com', 'contextchanged', '.contextsensitiv' ) message = AjaxMessage( 'Some info message', 'info', 'None' ) overlay = AjaxOverlay( selector='#ajax-overlay', action='someaction', target='http://example.com', close=False, content_selector='.overlay_content', css='additional-css-class' ) path = AjaxPath( 'foo/bar', target='http://example.com/foo/bar', action='layout:#layout:replace', event='contextchanged:#someid', overlay='acionname:#custom-overlay:.custom_overlay_content', overlay_css='additional-overlay-css-class' ) continuation = [action, event, message, overlay, path] afc = AjaxFormContinue(result, continuation) self.assertEqual(afc.form, '') afc_next = json.loads(afc.next) self.assertEqual(afc_next, [{ "mode": "replace", "selector": ".someselector", "type": "action", "target": "http://example.com", "name": "tilename" }, { "selector": ".contextsensitiv", "type": "event", "target": "http://example.com", "name": "contextchanged" }, { "flavor": "info", "type": "message", "payload": "Some info message", "selector": "None" }, { "target": "http://example.com", "content_selector": ".overlay_content", "selector": "#ajax-overlay", "action": "someaction", "close": False, "type": "overlay", "css": "additional-css-class" }, { "overlay_css": "additional-overlay-css-class", "target": "http://example.com/foo/bar", "overlay": "acionname:#custom-overlay:.custom_overlay_content", "action": "layout:#layout:replace", "path": "foo/bar", "type": "path", "event": "contextchanged:#someid" }])
def continuation(self, url): return [AjaxEvent(url, 'contextchanged', '#layout')]
def next(self, request): """Read ``came_from`` parameter from request and compute next URL. If ``came_from`` not found on request, ``default_came_from`` property is used. If ``came_from`` is special value ``parent``, URL of model parent is computed. If ``came_from`` is set, it is considered as URL to use. The given URL must match the basic application URL, otherwise an error gets logged and URL of current model is computed. If ``came_from`` is set to empty value, URL of current model is computed. """ # read came_from from request came_from = request.get('came_from') # fall back to default_came_from if came_from not passed on request if came_from is None: came_from = self.default_came_from # use model URL and path if no came_from if not came_from: url = make_url(request.request, node=self.model) path = '/'.join(node_path(self.model)) # use model parent URL and path if came_from is 'parent' elif came_from == 'parent': url = make_url(request.request, node=self.model.parent) path = '/'.join(node_path(self.model.parent)) # consider came_from a URL else: url = compat.unquote(came_from) parsed = compat.urlparse.urlparse(url) app_loc = compat.urlparse.urlparse( self.request.application_url).netloc # behave as if no came_from given if application location not # matches came_from location if app_loc != parsed.netloc: logger.error( ('CameFromNext.next(): Application location "{}" does not ' 'match came_from location "{}". Use model for URL ' 'computing instead').format(app_loc, parsed.netloc)) url = make_url(request.request, node=self.model) path = '/'.join(node_path(self.model)) # include query to path elif parsed.query: path = '{}?{}'.format(parsed.path, parsed.query) # query without path else: path = '{}'.format(parsed.path) # ajax continuation definitions if ajax request if self.ajax_request: event = AjaxEvent(url, 'contextchanged', '#layout') # return continuation path and event if browser history should be # written if self.write_history_on_next: cpath = AjaxPath(path, target=url, event='contextchanged:#layout') return [cpath, event] # return event only if writing browser history should be skipped return [event] # regular redirection if no ajax request return HTTPFound(location=url)
def render(self): cut = extract_copysupport_cookie(self.request, 'cut') copy = extract_copysupport_cookie(self.request, 'copy') localizer = get_localizer(self.request) if not cut and not copy: message = localizer.translate( _('nothing_to_paste', default='Nothing to paste')) ajax_message(self.request, message) return u'' urls = copy and copy or cut paths = paths_from_urls(urls) call_sources = set() errors = list() success = 0 for path in paths: node = self.model.root for key in path: node = node[key] if not node.node_info_name: message = localizer.translate(_( 'cannot_paste_unknown_source', default="Cannot paste '${name}'. Unknown source"), mapping={'name': node.name}) errors.append(message) continue if not self.model.node_info_name: message = localizer.translate( _('cannot_paste_unknown_target', default="Cannot paste to '${name}'. Unknown target"), mapping={'name': self.model.name}) errors.append(message) continue if node.node_info_name not in self.model.nodeinfo.addables: message = localizer.translate( _('cannot_paste_cardinality_violation', default=("Violation. '${target}' is not allowed to " "contain '${source}'")), mapping={ 'target': self.model.nodeinfo.title, 'source': node.nodeinfo.title }) errors.append(message) continue source = node.parent if copy: node = source[node.name].deepcopy() else: in_model = False for parent in LocationIterator(self.model): if parent is node: message = localizer.translate( _('cannot_paste_self_containment', default=("Cannot paste cut object to child " "of it: ${name}")), mapping={'name': parent.name}) errors.append(message) in_model = True break if in_model: continue node = source.detach(node.name) node.__parent__ = self.model self.model[choose_name(self.model, node.name)] = node if cut: call_sources.add(source) success += 1 if success > 0: self.model() for source in call_sources: source() message = localizer.translate(_('pasted_items', default="Pasted ${count} items"), mapping={'count': success}) if errors: failed = localizer.translate(_( 'pasting_items_failed', default="Pasting of ${count} items failed"), mapping={'count': len(errors)}) failed = "<br /><strong>%s</strong>" % failed message += "<br />".join([failed] + errors) ajax_message(self.request, message) content_tile = self.model.properties.action_paste_tile if not content_tile: content_tile = 'listing' query = make_query(contenttile=content_tile) url = make_url(self.request, node=self.model, query=query) event = AjaxEvent(url, 'contextchanged', '#layout') ajax_continue(self.request, event) res = self.request.response res.delete_cookie(cookie_name(copy and 'copy' or 'cut')) return u''