Repository: springload/draftjs_exporter

Issue:
Custom components switch places
I have two custom components: image and direct speech. There's nothing very fancy in their code, e.g. image is rendered like this:

```py
class Image:
    def render(self, props):
        data = props['block']['data']
        return self.wrapper(data)

    def wrapper(self, data):
        caption = data.get('caption', '')

        return tags.div(
            {'class': 'contentImage'},
            self.image(data),
            DOM.create_text_node(caption))

    def image(self, data):
        src = data.get('image', '')
        caption = data.get('caption', '')
        return tags.img({
            'src': src,
            'class': 'contentImage-image',
            'alt': caption})
```

then I generate the content for the blocks (not important fields are dropped):

```
{  
   "blocks":[  
      {  
         "text":"Start text",
         "type":"unstyled",
         ...
      },
      {  
         "type":"image",
         "data":{  
            "caption":"Some image caption",
            "image":"http://placekitten.com/401/402"
         },
         ...
      },
      {  
         "text":"Middle text",
         "type":"unstyled",
         ...
      },
      {  
         "type":"direct-speech",
         "data":{  
            "name":"Steve Jobs",
            "image":"http://placekitten.com/500/501",
            "text":"Hello, world!!!!111"
         },
         ...
      },
      {  
         "text":"Last text",
         "type":"unstyled",
         ...
      }
   ]
   ...
}
```

I expect "Middle text" block to be between the image and direct speech, but for some reason these two blocks are rendered together and the text appears before them:

```html
<p>Start text</p>
<p>Middle text</p>
<div>
   <div class="contentImage">
      <img class="contentImage-image" src="http://placekitten.com/401/402">Some image caption
   </div>
   <blockquote class="directSpeech">
      <div class="directSpeech-image" style="background-image: url(http://placekitten.com/500/501);"></div>
      <div class="directSpeech-wrapper">
         <div class="directSpeech-title">
            Steve Jobs
         </div>
         <p class="directSpeech-text">Hello, world!!!!111</p>
      </div>
   </blockquote>
</div>
<p>Last text</p>
```

I hope the bug is reproducable; if you have any questions or need more details I'll provide you any information.

Comments:

Patch:
diff --git a/draftjs_exporter/wrapper_state.py b/draftjs_exporter/wrapper_state.py
index 23db901..6eddd06 100644
--- a/draftjs_exporter/wrapper_state.py
+++ b/draftjs_exporter/wrapper_state.py
@@ -116,10 +116,7 @@ class WrapperState:
             DOM.append_child(parent, elt)
         else:
             # Reset the stack if there is no wrapper.
-            head = self.stack.head()
-            if self.stack.length() > 0 and head.depth != -1 and head.props is not None:
-                self.stack.slice(-1)
-                self.stack.append(Wrapper(-1, None))
+            self.stack = WrapperStack()
             parent = elt
 
         return parent


Test patch:
diff --git a/tests/test_output.py b/tests/test_output.py
index 0c61693..76de968 100644
--- a/tests/test_output.py
+++ b/tests/test_output.py
@@ -5,15 +5,26 @@ import unittest
 
 from draftjs_exporter.constants import BLOCK_TYPES, ENTITY_TYPES, INLINE_STYLES
 from draftjs_exporter.defaults import BLOCK_MAP
+from draftjs_exporter.dom import DOM
 from draftjs_exporter.entity_state import EntityException
 from draftjs_exporter.html import HTML
 from tests.test_composite_decorators import BR, Hashtag, Linkify
-from tests.test_entities import HR, Link
+from tests.test_entities import HR, Image, Link
+
+
+def Blockquote(props):
+    block_data = props['block']['data']
+
+    return DOM.create_element('blockquote', {
+        'cite': block_data.get('cite')
+    }, props['children'])
+
 
 config = {
     'entity_decorators': {
         ENTITY_TYPES.LINK: Link,
         ENTITY_TYPES.HORIZONTAL_RULE: HR,
+        ENTITY_TYPES.IMAGE: Image
     },
     'composite_decorators': [
         Linkify,
@@ -26,6 +37,10 @@ config = {
             'wrapper': 'ul',
             'wrapper_props': {'className': 'steps'},
         },
+        'blockquote': {
+            'element': Blockquote,
+            'wrapper': 'div',
+        },
     }),
     'style_map': {
         INLINE_STYLES.CODE: 'code',
@@ -496,6 +511,106 @@ class TestOutput(unittest.TestCase):
             ]
         }), '<ul class="steps"><li>item1</li><li>item2</li></ul><hr/>')
 
+    def test_render_with_wrapping_reset(self):
+        self.assertEqual(self.exporter.render({
+            'entityMap': {},
+            'blocks': [
+                {
+                    'key': '93agv',
+                    'text': '1',
+                    'type': 'unstyled',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': '4ht9m',
+                    'text': '2',
+                    'type': 'unordered-list-item',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': 'c6gc4',
+                    'text': '3',
+                    'type': 'unstyled',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': 'c6gc3',
+                    'text': '4',
+                    'type': 'unordered-list-item',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': '3mn5b',
+                    'text': '5',
+                    'type': 'unstyled',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+            ],
+        }), '<p>1</p><ul class="steps"><li>2</li></ul><p>3</p><ul class="steps"><li>4</li></ul><p>5</p>')
+
+    def test_render_with_wrapping_reset_block_components(self):
+        self.assertEqual(self.exporter.render({
+            'entityMap': {},
+            'blocks': [
+                {
+                    'key': '93agv',
+                    'text': '1',
+                    'type': 'unstyled',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': '4ht9m',
+                    'text': '2',
+                    'type': 'blockquote',
+                    'depth': 0,
+                    'data': {
+                        'cite': '2'
+                    },
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': 'c6gc4',
+                    'text': '3',
+                    'type': 'unstyled',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': 'c6gc3',
+                    'text': '4',
+                    'type': 'blockquote',
+                    'depth': 0,
+                    'data': {
+                        'cite': '4'
+                    },
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+                {
+                    'key': '3mn5b',
+                    'text': '5',
+                    'type': 'unstyled',
+                    'depth': 0,
+                    'inlineStyleRanges': [],
+                    'entityRanges': [],
+                },
+            ],
+        }), '<p>1</p><div><blockquote cite="2">2</blockquote></div><p>3</p><div><blockquote cite="4">4</blockquote></div><p>5</p>')
+
     def test_render_with_unidirectional_nested_wrapping(self):
         self.assertEqual(self.exporter.render({
             'entityMap': {},