diff --git a/wagtail/admin/rich_text/converters/html_to_contentstate.py b/wagtail/admin/rich_text/converters/html_to_contentstate.py index 8caa5c6bc..c5c34d3c6 100644 --- a/wagtail/admin/rich_text/converters/html_to_contentstate.py +++ b/wagtail/admin/rich_text/converters/html_to_contentstate.py @@ -213,6 +213,11 @@ class ImageElementHandler(AtomicBlockEntityElementHandler): return Entity('IMAGE', 'IMMUTABLE', {'altText': attrs.get('alt'), 'id': attrs['id'], 'format': attrs['format']}) +class MediaEmbedElementHandler(AtomicBlockEntityElementHandler): + def create_entity(self, name, attrs, state, contentstate): + return Entity('EMBED', 'IMMUTABLE', {'url': attrs['url']}) + + ELEMENT_HANDLERS_BY_FEATURE = { 'ol': { 'ol': ListElementHandler('ordered-list-item'), @@ -258,6 +263,9 @@ ELEMENT_HANDLERS_BY_FEATURE = { 'image': { 'embed[embedtype="image"]': ImageElementHandler(), }, + 'embed': { + 'embed[embedtype="media"]': MediaEmbedElementHandler(), + }, } diff --git a/wagtail/admin/tests/test_contentstate.py b/wagtail/admin/tests/test_contentstate.py index 1abeb5abb..236d82926 100644 --- a/wagtail/admin/tests/test_contentstate.py +++ b/wagtail/admin/tests/test_contentstate.py @@ -345,3 +345,26 @@ class TestHtmlToContentState(TestCase): } } }) + + def test_media_embed(self): + converter = ContentstateConverter(features=['embed']) + result = json.loads(converter.from_database_format( + ''' +
before
+ +after
+ ''' + )) + self.assertContentStateEqual(result, { + 'blocks': [ + {'key': '00000', 'inlineStyleRanges': [], 'entityRanges': [], 'depth': 0, 'text': 'before', 'type': 'unstyled'}, + {'key': '00000', 'inlineStyleRanges': [], 'entityRanges': [{'key': 0, 'offset': 0, 'length': 1}], 'depth': 0, 'text': ' ', 'type': 'atomic'}, + {'key': '00000', 'inlineStyleRanges': [], 'entityRanges': [], 'depth': 0, 'text': 'after', 'type': 'unstyled'} + ], + 'entityMap': { + '0': { + 'data': {'url': 'https://www.youtube.com/watch?v=Kh0Y2hVe_bw'}, + 'mutability': 'IMMUTABLE', 'type': 'EMBED' + } + } + })