def add_dropdown(self, title, dropdown_menu, drop_position='down', query_arguments={}): """Adds the dropdown_menu :class:`DropdownMenu` to this Nav. It appears as the top-level item with text `title`. :keyword drop_position: Position relative to the item where the dropdown should appear ('up', 'down', 'left' or 'right'). :keyword query_arguments: (For internal use) """ if self.open_item == title: extra_query_arguments = {'open_item': ''} else: extra_query_arguments = {'open_item': title} extra_query_arguments.update(query_arguments) bookmark = Bookmark.for_widget( title, query_arguments=extra_query_arguments).on_view(self.view) submenu = MenuItem(self.view, A.from_bookmark(self.view, bookmark)) self.menu_items.append(submenu) li = self.add_html_for_item(submenu) li.add_child(dropdown_menu) if self.open_item == title: li.append_class('show') submenu.a.append_class('dropdown-toggle') submenu.a.set_attribute('data-toggle', 'dropdown') submenu.a.set_attribute('role', 'button') submenu.a.set_attribute('aria-haspopup', 'true') # submenu.a.set_attribute('aria-expanded', 'true') #FYI no need to set this this as it is handled by bootstrap js li.append_class(DropdownMenuPosition(drop_position).as_html_snippet()) return submenu
def add_dropdown(self, title, dropdown_menu, drop_up=False, query_arguments={}): """Adds the dropdown_menu :class:`DropdownMenu` to this Nav. It appears as the top-level item with text `title`. :keyword drop_up: If True, the dropdown will drop upwards from its item, instead of down. :keyword query_arguments: (For internal use) """ if self.open_item == title: extra_query_arguments = {'open_item': ''} else: extra_query_arguments = {'open_item': title} extra_query_arguments.update(query_arguments) bookmark = Bookmark.for_widget( title, query_arguments=extra_query_arguments).on_view(self.view) submenu = MenuItem(self.view, A.from_bookmark(self.view, bookmark)) self.menu_items.append(submenu) li = self.add_html_for_item(submenu) li.add_child(dropdown_menu) if self.open_item == title: li.append_class('open') submenu.a.append_class('dropdown-toggle') submenu.a.set_attribute('data-toggle', 'dropdown') submenu.a.set_attribute('data-target', '-') submenu.a.add_child(Span(self.view)).append_class('caret') li.append_class('drop%s' % ('up' if drop_up else 'down')) return submenu
def get_bookmark(self, start_page_number=1, disabled=False): bookmark = Bookmark.for_widget( None, query_arguments={ 'start_page_number': start_page_number, 'current_page_number': self.page_index.current_page_number }, write_check=lambda: not disabled).on_view(self.view) return bookmark
def create_sorter_link(self, column_number, heading_widget): show_control = (column_number == self.page_index.sort_column_number) if show_control: sort_descending = 'off' if self.page_index.sort_descending else 'on' link_class = 'sorted-descending' if sort_descending=='off' else 'sorted-ascending' else: sort_descending = 'off' link_class = None bookmark = Bookmark.for_widget(None, query_arguments={'sort_column_number': column_number, 'sort_descending': sort_descending}) link = A.from_bookmark(self.view, bookmark.on_view(self.view)) link.add_child(heading_widget) if link_class: link.append_class(link_class) return link
def bookmarks_support_such_fragments(self, fixture): """Page-internal bookmarks support such bookmarkable widgets. These Bookmarks usually do not affect an URL - they just set widget states in different ways, depending on whether the client has javascript support or not. However, if a page was opened using the widget arguments on the querystring, a bookmark that would normally only have changed that argument on the hash will point to a new url on which the argument has been removed from the querystring and changed on the hash. """ internal_bookmark = Bookmark.for_widget( 'an ajax bookmark', query_arguments={'fancy_state': 2}) normal_bookmark = Bookmark('/', '', 'a normal bookmark') # You can query whether a bookmark is page_internal or not vassert(internal_bookmark.is_page_internal) vassert(not normal_bookmark.is_page_internal) # page-internal bookmarks must be added to normal ones to be useful usable_bookmark = normal_bookmark + internal_bookmark wsgi_app = fixture.new_wsgi_app( widget_factory=A.factory_from_bookmark(usable_bookmark)) # Case: when rendered without javascript browser = Browser(wsgi_app) browser.open('/') a = browser.lxml_html.xpath('//a')[0] vassert(a.attrib['href'] == '/?fancy_state=2') vassert(a.text == 'an ajax bookmark') # Case: when rendered in a browser with javascript support fixture.reahl_server.set_app(wsgi_app) fixture.driver_browser.open('/') vassert( fixture.driver_browser.is_element_present( "//a[@href='/#fancy_state=2']")) vassert(not fixture.driver_browser.is_element_present( "//a[@href='/?fancy_state=2']")) # Case: when the argument was given on the query string of the current page fixture.driver_browser.open('/?fancy_state=4') vassert( fixture.driver_browser.is_element_present( "//a[@href='/#fancy_state=2']"))
def test_bookmark_rights_when_adding(rights_scenarios): """When adding two Bookmarks, access rights of both are taken into account. """ fixture = rights_scenarios internal_bookmark = Bookmark.for_widget('an ajax bookmark', query_arguments={'fancy_state':2}, read_check=fixture.internal_readable, write_check=fixture.internal_writable) normal_bookmark = Bookmark('/', '', 'a normal bookmark', read_check=fixture.normal_readable, write_check=fixture.normal_writable) usable_bookmark = normal_bookmark+internal_bookmark assert usable_bookmark.read_check() is fixture.expected_readable assert usable_bookmark.write_check() is fixture.expected_writable
def get_bookmark(self, description=None, page_number=1): return Bookmark.for_widget(description or '%s' % page_number, query_arguments={'current_page_number': page_number}).on_view(self.view)
def get_bookmark(self, for_selected): return Bookmark.for_widget('Select %s' % for_selected, query_arguments={ 'selected': for_selected }).on_view(self.view)