52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
from typing import List, Sequence
|
||
|
||
from draftjs_exporter.command import Command
|
||
from draftjs_exporter.constants import INLINE_STYLES
|
||
from draftjs_exporter.dom import DOM
|
||
from draftjs_exporter.options import Options, OptionsMap
|
||
from draftjs_exporter.types import Block, Element
|
||
|
||
|
||
class StyleState:
|
||
"""
|
||
Handles the creation of inline styles on elements.
|
||
Receives inline_style commands, and generates the element's `style`
|
||
attribute from those.
|
||
"""
|
||
|
||
__slots__ = ("styles", "style_options")
|
||
|
||
def __init__(self, style_options: OptionsMap) -> None:
|
||
self.styles: List[str] = []
|
||
self.style_options = style_options
|
||
|
||
def apply(self, command: Command) -> None:
|
||
if command.name == "start_inline_style":
|
||
self.styles.append(command.data)
|
||
elif command.name == "stop_inline_style":
|
||
self.styles.remove(command.data)
|
||
|
||
def is_empty(self) -> bool:
|
||
return not self.styles
|
||
|
||
def render_styles(
|
||
self, decorated_node: Element, block: Block, blocks: Sequence[Block]
|
||
) -> Element:
|
||
node = decorated_node
|
||
if not self.is_empty():
|
||
# This will mutate self.styles, but it’s going to be reset after rendering anyway.
|
||
self.styles.sort(reverse=True)
|
||
|
||
# Nest the tags.
|
||
for style in self.styles:
|
||
options = Options.get(
|
||
self.style_options, style, INLINE_STYLES.FALLBACK
|
||
)
|
||
props = dict(options.props)
|
||
props["block"] = block
|
||
props["blocks"] = blocks
|
||
props["inline_style_range"] = {"style": style}
|
||
node = DOM.create_element(options.element, props, node)
|
||
|
||
return node
|