def render_block(self, block, entity_map, wrapper_state): if block['inlineStyleRanges'] or block['entityRanges']: content = DOM.create_element() entity_state = EntityState(self.entity_decorators, entity_map) style_state = StyleState(self.style_map) for (text, commands) in self.build_command_groups(block): for command in commands: entity_state.apply(command) style_state.apply(command) # Decorators are not rendered inside entities. if entity_state.has_no_entity() and self.has_decorators: decorated_node = render_decorators(self.composite_decorators, text, block, wrapper_state.blocks) else: decorated_node = text styled_node = style_state.render_styles(decorated_node, block, wrapper_state.blocks) entity_node = entity_state.render_entities(styled_node) if entity_node is not None: DOM.append_child(content, entity_node) # Check whether there actually are two different nodes, confirming we are not inserting an upcoming entity. if styled_node != entity_node and entity_state.has_no_entity(): DOM.append_child(content, styled_node) # Fast track for blocks which do not contain styles nor entities, which is very common. elif self.has_decorators: content = render_decorators(self.composite_decorators, block['text'], block, wrapper_state.blocks) else: content = block['text'] return wrapper_state.element_for(block, content)
def render_block(self, block: Block, entity_map: EntityMap, wrapper_state: WrapperState) -> Element: has_styles = "inlineStyleRanges" in block and block["inlineStyleRanges"] has_entities = "entityRanges" in block and block["entityRanges"] has_decorators = should_render_decorators(self.composite_decorators, block["text"]) if has_styles or has_entities: content = DOM.create_element() entity_state = EntityState(self.entity_options, entity_map) style_state = StyleState( self.style_options) if has_styles else None for (text, commands) in self.build_command_groups(block): for command in commands: entity_state.apply(command) if style_state: style_state.apply(command) # Decorators are not rendered inside entities. if has_decorators and entity_state.has_no_entity(): decorated_node = render_decorators( self.composite_decorators, text, block, wrapper_state.blocks, ) else: decorated_node = text if style_state: styled_node = style_state.render_styles( decorated_node, block, wrapper_state.blocks) else: styled_node = decorated_node entity_node = entity_state.render_entities( styled_node, block, wrapper_state.blocks) if entity_node is not None: DOM.append_child(content, entity_node) # Check whether there actually are two different nodes, confirming we are not inserting an upcoming entity. if (styled_node != entity_node and entity_state.has_no_entity()): DOM.append_child(content, styled_node) # Fast track for blocks which do not contain styles nor entities, which is very common. elif has_decorators: content = render_decorators( self.composite_decorators, block["text"], block, wrapper_state.blocks, ) else: content = block["text"] return wrapper_state.element_for(block, content)
def render_block(self, block, entity_map, wrapper_state): content = DOM.create_element() entity_state = EntityState(self.entity_decorators, entity_map) style_state = StyleState(self.style_map) for (text, commands) in self.build_command_groups(block): for command in commands: entity_state.apply(command) style_state.apply(command) # Decorators are not rendered inside entities. if text and entity_state.has_no_entity() and len( self.composite_decorators) > 0: decorated_node = render_decorators(self.composite_decorators, text, block) else: decorated_node = text styled_node = style_state.render_styles(decorated_node) entity_node = entity_state.render_entities(styled_node) if entity_node is not None: DOM.append_child(content, entity_node) if styled_node != entity_node: DOM.append_child(content, styled_node) return wrapper_state.element_for(block, content)
def test_render_decorators_empty(self): self.assertEqual( render_decorators([], 'test https://www.example.com#hash #hashtagtest', { 'type': BLOCK_TYPES.UNSTYLED, 'depth': 0 }), 'test https://www.example.com#hash #hashtagtest')
def test_render_decorators_single(self): self.assertEqual( DOM.render( render_decorators( [LINKIFY_DECORATOR], 'test https://www.example.com#hash #hashtagtest', { 'type': BLOCK_TYPES.UNSTYLED, 'depth': 0 })), 'test <a href="https://www.example.com#hash">https://www.example.com#hash</a> #hashtagtest' )
def test_render_decorators_conflicting_order_two(self): self.assertEqual( DOM.render( render_decorators( [HASHTAG_DECORATOR, LINKIFY_DECORATOR], 'test https://www.example.com#hash #hashtagtest', { 'type': BLOCK_TYPES.UNSTYLED, 'depth': 0 })), 'test https://www.example.com<span class="hashtag">#hash</span> <span class="hashtag">#hashtagtest</span>' )
def render_block(self, block, entity_map, wrapper_state): if 'inlineStyleRanges' in block and block[ 'inlineStyleRanges'] or 'entityRanges' in block and block[ 'entityRanges']: content = DOM.create_element() entity_state = EntityState(self.entity_options, entity_map) style_state = StyleState(self.style_options) for (text, commands) in self.build_command_groups(block): for command in commands: entity_state.apply(command) style_state.apply(command) # Decorators are not rendered inside entities. if entity_state.has_no_entity() and self.has_decorators: decorated_node = render_decorators( self.composite_decorators, text, block, wrapper_state.blocks) else: decorated_node = text styled_node = style_state.render_styles( decorated_node, block, wrapper_state.blocks) entity_node = entity_state.render_entities(styled_node) if entity_node is not None: DOM.append_child(content, entity_node) # Check whether there actually are two different nodes, confirming we are not inserting an upcoming entity. if styled_node != entity_node and entity_state.has_no_entity( ): DOM.append_child(content, styled_node) # Fast track for blocks which do not contain styles nor entities, which is very common. elif self.has_decorators: content = render_decorators(self.composite_decorators, block['text'], block, wrapper_state.blocks) else: content = block['text'] return wrapper_state.element_for(block, content)
def render_block(self, block, entity_map, wrapper_state): content = DOM.create_element() if block['inlineStyleRanges'] or block['entityRanges']: entity_state = EntityState(self.entity_decorators, entity_map) style_state = StyleState(self.style_map) for (text, commands) in self.build_command_groups(block): for command in commands: entity_state.apply(command) style_state.apply(command) # Decorators are not rendered inside entities. if text and entity_state.has_no_entity() and len( self.composite_decorators) > 0: decorated_node = render_decorators( self.composite_decorators, text, block, wrapper_state.blocks) else: decorated_node = text styled_node = style_state.render_styles( decorated_node, block, wrapper_state.blocks) entity_node = entity_state.render_entities(styled_node) if entity_node is not None: DOM.append_child(content, entity_node) if styled_node != entity_node: DOM.append_child(content, styled_node) # Fast track for blocks which do not contain styles nor entities, which is very common. else: if len(self.composite_decorators) > 0: decorated_node = render_decorators(self.composite_decorators, block['text'], block, wrapper_state.blocks) else: decorated_node = block['text'] DOM.append_child(content, decorated_node) return wrapper_state.element_for(block, content)
def test_render_decorators_empty(self): self.assertEqual( render_decorators( [], "test https://www.example.com#hash #hashtagtest", { "type": BLOCK_TYPES.UNSTYLED, "depth": 0 }, [], ), "test https://www.example.com#hash #hashtagtest", )
def test_render_decorators_conflicting_order_one(self): self.assertEqual( DOM.render( render_decorators( [LINKIFY_DECORATOR, HASHTAG_DECORATOR], "test https://www.example.com#hash #hashtagtest", { "type": BLOCK_TYPES.UNSTYLED, "depth": 0 }, [], )), 'test <a href="https://www.example.com#hash">https://www.example.com#hash</a> <span class="hashtag">#hashtagtest</span>', )
def test_render_decorators_data(self): blocks = [ { 'key': '5s7g9', 'text': 'test', 'type': 'unstyled', 'depth': 0, 'inlineStyleRanges': [], 'entityRanges': [], }, ] def component(props): self.assertEqual(props['blocks'], blocks) self.assertEqual(props['block'], blocks[0]) return None render_decorators([ { 'strategy': LINKIFY_RE, 'component': component, }, ], 'test https://www.example.com#hash #hashtagtest', blocks[0], blocks)
def test_render_decorators_data(self): blocks = [{ "key": "5s7g9", "text": "test", "type": "unstyled", "depth": 0, "inlineStyleRanges": [], "entityRanges": [], }] def component(props): self.assertEqual(props["blocks"], blocks) self.assertEqual(props["block"], blocks[0]) return None render_decorators( [{ "strategy": LINKIFY_RE, "component": component }], "test https://www.example.com#hash #hashtagtest", blocks[0], blocks, )
def test_render(self): self.assertEqual( DOM.render( DOM.create_element(br, {"block": { "type": BLOCK_TYPES.UNSTYLED }}, "\n")), "<br/>", ) self.assertEqual( DOM.render( render_decorators( [BR_DECORATOR], "test \n test", { "type": BLOCK_TYPES.UNSTYLED, "depth": 0 }, [], )), "test <br/> test", )
def test_render_decorators_empty(self): self.assertEqual(render_decorators([], 'test https://www.example.com#hash #hashtagtest', {'type': BLOCK_TYPES.UNSTYLED, 'depth': 0}, []), 'test https://www.example.com#hash #hashtagtest')
def test_render_decorators_single(self): self.assertEqual(DOM.render(render_decorators([LINKIFY_DECORATOR], 'test https://www.example.com#hash #hashtagtest', {'type': BLOCK_TYPES.UNSTYLED, 'depth': 0}, [])), 'test <a href="https://www.example.com#hash">https://www.example.com#hash</a> #hashtagtest')
def test_render_decorators_conflicting_order_two(self): self.assertEqual(DOM.render(render_decorators([HASHTAG_DECORATOR, LINKIFY_DECORATOR], 'test https://www.example.com#hash #hashtagtest', {'type': BLOCK_TYPES.UNSTYLED, 'depth': 0}, [])), 'test https://www.example.com<span class="hashtag">#hash</span> <span class="hashtag">#hashtagtest</span>')