@@ -63,6 +63,7 @@ def __init__(self, message: Message, model: "Model", last_message: Any) -> None:
63
63
self .message_links : Dict [str , Tuple [str , int , bool ]] = dict ()
64
64
self .topic_links : Dict [str , Tuple [str , int , bool ]] = dict ()
65
65
self .time_mentions : List [Tuple [str , str ]] = list ()
66
+ self .spoilers : List [Tuple [int , List [Any ], List [Any ]]] = list ()
66
67
self .last_message = last_message
67
68
# if this is the first message
68
69
if self .last_message is None :
@@ -371,12 +372,22 @@ def footlinks_view(
371
372
@classmethod
372
373
def soup2markup (
373
374
cls , soup : Any , metadata : Dict [str , Any ], ** state : Any
374
- ) -> Tuple [List [Any ], Dict [str , Tuple [str , int , bool ]], List [Tuple [str , str ]]]:
375
+ ) -> Tuple [
376
+ List [Any ],
377
+ Dict [str , Tuple [str , int , bool ]],
378
+ List [Tuple [str , str ]],
379
+ List [Tuple [int , List [Any ], List [Any ]]],
380
+ ]:
375
381
# Ensure a string is provided, in case the soup finds none
376
382
# This could occur if eg. an image is removed or not shown
377
383
markup : List [Union [str , Tuple [Optional [str ], Any ]]] = ["" ]
378
384
if soup is None : # This is not iterable, so return promptly
379
- return markup , metadata ["message_links" ], metadata ["time_mentions" ]
385
+ return (
386
+ markup ,
387
+ metadata ["message_links" ],
388
+ metadata ["time_mentions" ],
389
+ metadata ["spoilers" ],
390
+ )
380
391
unrendered_tags = { # In pairs of 'tag_name': 'text'
381
392
# TODO: Some of these could be implemented
382
393
"br" : "" , # No indicator of absence
@@ -647,6 +658,10 @@ def soup2markup(
647
658
part [1 ] if isinstance (part , tuple ) else part
648
659
for part in processed_header
649
660
)
661
+ header_len = sum (
662
+ len (part [1 ]) if isinstance (part , tuple ) else len (part )
663
+ for part in processed_header
664
+ )
650
665
651
666
# Limit to the first 10 characters and append "..."
652
667
if len (processed_header_text ) > 10 :
@@ -671,9 +686,33 @@ def soup2markup(
671
686
]
672
687
)
673
688
markup .extend (bottom_border )
689
+ # Spoiler content
690
+ content = element .find (class_ = "spoiler-content" )
691
+
692
+ # Remove surrounding newlines.
693
+ content_contents = content .contents
694
+ if len (content_contents ) > 2 :
695
+ if content_contents [- 1 ] == "\n " :
696
+ content .contents .pop (- 1 )
697
+ if content_contents [0 ] == "\n " :
698
+ content .contents .pop (0 )
699
+ if len (content_contents ) == 1 and content_contents [0 ] == "\n " :
700
+ content .contents .pop (0 )
701
+
702
+ # FIXME: Do not soup2markup content in the MessageBox as it
703
+ # will render 'sensitive' spoiler anchor tags in the footlinks.
704
+ processed_content = cls .soup2markup (content , metadata )[0 ]
705
+ metadata ["spoilers" ].append (
706
+ (header_len , processed_header , processed_content )
707
+ )
674
708
else :
675
709
markup .extend (cls .soup2markup (element , metadata )[0 ])
676
- return markup , metadata ["message_links" ], metadata ["time_mentions" ]
710
+ return (
711
+ markup ,
712
+ metadata ["message_links" ],
713
+ metadata ["time_mentions" ],
714
+ metadata ["spoilers" ],
715
+ )
677
716
678
717
def main_view (self ) -> List [Any ]:
679
718
# Recipient Header
@@ -769,9 +808,12 @@ def main_view(self) -> List[Any]:
769
808
)
770
809
771
810
# Transform raw message content into markup (As needed by urwid.Text)
772
- content , self .message_links , self .time_mentions = self .transform_content (
773
- self .message ["content" ], self .model .server_url
774
- )
811
+ (
812
+ content ,
813
+ self .message_links ,
814
+ self .time_mentions ,
815
+ self .spoilers ,
816
+ ) = self .transform_content (self .message ["content" ], self .model .server_url )
775
817
self .content .set_text (content )
776
818
777
819
if self .message ["id" ] in self .model .index ["edited_messages" ]:
@@ -858,6 +900,7 @@ def transform_content(
858
900
Tuple [None , Any ],
859
901
Dict [str , Tuple [str , int , bool ]],
860
902
List [Tuple [str , str ]],
903
+ List [Tuple [int , List [Any ], List [Any ]]],
861
904
]:
862
905
soup = BeautifulSoup (content , "lxml" )
863
906
body = soup .find (name = "body" )
@@ -866,13 +909,14 @@ def transform_content(
866
909
server_url = server_url ,
867
910
message_links = dict (),
868
911
time_mentions = list (),
912
+ spoilers = list (),
869
913
) # type: Dict[str, Any]
870
914
871
915
if isinstance (body , Tag ) and body .find (name = "blockquote" ):
872
916
metadata ["bq_len" ] = cls .indent_quoted_content (soup , QUOTED_TEXT_MARKER )
873
917
874
- markup , message_links , time_mentions = cls .soup2markup (body , metadata )
875
- return (None , markup ), message_links , time_mentions
918
+ markup , message_links , time_mentions , spoilers = cls .soup2markup (body , metadata )
919
+ return (None , markup ), message_links , time_mentions , spoilers
876
920
877
921
@staticmethod
878
922
def indent_quoted_content (soup : Any , padding_char : str ) -> int :
0 commit comments