Skip to content

Commit

Permalink
[WIP] Load StreamField as the DOM loads rather than at the end
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaudcolas authored and BertrandBordage committed Feb 26, 2019
1 parent 14fc7e8 commit 73e01f2
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
39 changes: 25 additions & 14 deletions client/src/components/StreamField/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,30 @@ import { StreamField, streamFieldReducer } from 'react-streamfield';

const store = createStore(streamFieldReducer, applyMiddleware(thunk));

export const initStreamField = () => {
for (const streamfieldNode of document.querySelectorAll('script[data-streamfield]')) {
const newNode = streamfieldNode.parentNode.insertBefore(document.createElement('div'), streamfieldNode);
const id = streamfieldNode.getAttribute('data-streamfield');
const init = (name, options, currentScript) => {
// document.currentScript is not available in IE11. Use a fallback instead.
const context = currentScript ? currentScript.parentNode : document.body;
// If the field is not in the current context, look for it in the whole body.
// Fallback for sequence.js jQuery eval-ed scripts running in document.head.
const selector = `[name="${name}"]`;
const field = (context.querySelector(selector)
|| document.body.querySelector(selector));

ReactDOM.render(
<Provider store={store}>
<StreamField
{...JSON.parse(streamfieldNode.innerHTML)}
id={id}
/>
</Provider>,
newNode
);
}
const wrapper = document.createElement('div');

field.parentNode.appendChild(wrapper);

ReactDOM.render(
<Provider store={store}>
<StreamField
{...options}
id={name}
/>
</Provider>,
wrapper
);
};

export default {
init,
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { initStreamField } from '../../../../../client/src/components/StreamField/index';
import streamField from '../../../../../client/src/components/StreamField/index';

document.addEventListener('DOMContentLoaded', () => {
initStreamField();
});
window.streamField = streamField;
7 changes: 4 additions & 3 deletions wagtail/core/blocks/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,11 +527,12 @@ def render_with_errors(self, name, value, attrs=None, errors=None,
mark_safe('<div class="help-block help-critical">%s</div>') % error
for error in non_block_errors])
return mark_safe("""
<script type="application/json" data-streamfield="%s">%s</script>
<textarea style="display: none;" name="%s">%s</textarea>
<script>window.streamField.init('%s', %s, document.currentScript)</script>
%s
""" % (name, to_json_script(streamfield_config),
name, escaped_value, non_block_errors))
""" % (name, escaped_value,
name, to_json_script(streamfield_config),
non_block_errors))

def render(self, name, value, attrs=None, renderer=None):
return self.render_with_errors(name, value, attrs=attrs, errors=None, renderer=renderer)
Expand Down

0 comments on commit 73e01f2

Please sign in to comment.