Extract styles and scripts
This commit is contained in:
parent
5bb7f243f5
commit
62813e41a3
3 changed files with 67 additions and 19 deletions
|
@ -2,8 +2,8 @@
|
|||
|
||||
window.addEventListener('message', receiveMessage, false);
|
||||
|
||||
var concreteDOM;
|
||||
var virtualDOM;
|
||||
var concreteDom;
|
||||
var virtualDom;
|
||||
var goalStates;
|
||||
|
||||
var allowedOrigins = [
|
||||
|
@ -19,7 +19,7 @@ function receiveMessage(event) {
|
|||
var origin = event.origin || event.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object.
|
||||
var allowed = false;
|
||||
allowedOrigins.forEach(function(pattern) {
|
||||
allowed = allowed || pattern.test(origin);
|
||||
allowed = allowed || pattern.test(origin);
|
||||
});
|
||||
if (!allowed) {
|
||||
console.log('Ignoring message from bad origin:', origin);
|
||||
|
@ -30,14 +30,14 @@ function receiveMessage(event) {
|
|||
var source = event.source;
|
||||
switch (data.type) {
|
||||
case 'create':
|
||||
create(data.dom);
|
||||
create(_.pick(data, 'dom', 'styles', 'scripts'));
|
||||
checkGoals(data.goals, source, origin);
|
||||
break;
|
||||
case 'update':
|
||||
if (virtualDOM)
|
||||
update(data.dom);
|
||||
if (virtualDom)
|
||||
update(_.pick(data, 'dom', 'styles', 'scripts'));
|
||||
else
|
||||
create(data.dom);
|
||||
create(_.pick(data, 'dom', 'styles', 'scripts'));
|
||||
checkGoals(data.goals, source, origin);
|
||||
break;
|
||||
case 'log':
|
||||
|
@ -48,20 +48,40 @@ function receiveMessage(event) {
|
|||
}
|
||||
}
|
||||
|
||||
function create(dom) {
|
||||
virtualDOM = dom;
|
||||
concreteDOM = deku.dom.create(dom);
|
||||
function create({ dom, styles, scripts }) {
|
||||
virtualDom = dom;
|
||||
virtualStyles = styles;
|
||||
virtualScripts = scripts;
|
||||
concreteDom = deku.dom.create(dom);
|
||||
concreteStyles = styles.map(function(style){return deku.dom.create(style)});
|
||||
concreteScripts = scripts.map(function(script){return deku.dom.create(script)});
|
||||
// TODO: target the actual HTML tag and combine our initial structure for styles/scripts/tags with theirs
|
||||
// TODO: :after elements don't seem to work? (:before do)
|
||||
$('body').empty().append(concreteDOM);
|
||||
$('body').first().empty().append(concreteDom);
|
||||
$('#player-styles').first().empty().append(concreteStyles);
|
||||
$('#player-scripts').first().empty().append(concreteScripts);
|
||||
}
|
||||
|
||||
function update(dom) {
|
||||
function update({ dom, styles, scripts }) {
|
||||
function dispatch() {} // Might want to do something here in the future
|
||||
var context = {}; // Might want to use this to send shared state to every component
|
||||
var changes = deku.diff.diffNode(virtualDOM, dom);
|
||||
changes.reduce(deku.dom.update(dispatch, context), concreteDOM); // Rerender
|
||||
virtualDOM = dom;
|
||||
var domChanges = deku.diff.diffNode(virtualDom, dom);
|
||||
domChanges.reduce(deku.dom.update(dispatch, context), concreteDom); // Rerender
|
||||
|
||||
var scriptChanges = virtualScripts.map(function(virtualScript, index){
|
||||
return deku.diff.diffNode(virtualScripts[index], scripts[index]);
|
||||
});
|
||||
scriptChanges.forEach(function(scriptChange, index){
|
||||
scriptChange.reduce(deku.dom.update(dispatch, context), concreteStyles[index])
|
||||
});
|
||||
|
||||
var styleChanges = virtualStyles.map(function(virtualStyle, index){
|
||||
return deku.diff.diffNode(virtualStyles[index], styles[index]);
|
||||
});
|
||||
styleChanges.forEach(function(styleChange, index){
|
||||
styleChange.reduce(deku.dom.update(dispatch, context), concreteStyles[index])
|
||||
});
|
||||
virtualDom = dom;
|
||||
}
|
||||
|
||||
function checkGoals(goals, source, origin) {
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Extracted player/level styles and scripts -->
|
||||
<style id="player-styles">
|
||||
</style>
|
||||
<script id="player-scripts">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Loading...</h1>
|
||||
|
|
|
@ -31,18 +31,40 @@ module.exports = class WebSurfaceView extends CocoView
|
|||
body = _.find(dom, name: 'body') ? {name: 'body', attribs: null, children: dom}
|
||||
html = _.find(dom, name: 'html') ? {name: 'html', attribs: null, children: [body]}
|
||||
# TODO: pull out the actual scripts, styles, and body/elements they are doing so we can merge them with our initial structure on the other side
|
||||
virtualDOM = @dekuify html
|
||||
messageType = if e.create or not @virtualDOM then 'create' else 'update'
|
||||
@iframe.contentWindow.postMessage {type: messageType, dom: virtualDOM, goals: @goals}, '*'
|
||||
@virtualDOM = virtualDOM
|
||||
{ virtualDom, styles, scripts } = @extractStylesAndScripts(@dekuify html)
|
||||
messageType = if e.create or not @virtualDom then 'create' else 'update'
|
||||
@iframe.contentWindow.postMessage {type: messageType, dom: virtualDom, styles, scripts, goals: @goals}, '*'
|
||||
@virtualDom = virtualDom
|
||||
|
||||
dekuify: (elem) ->
|
||||
return elem.data if elem.type is 'text'
|
||||
return null if elem.type is 'comment' # TODO: figure out how to make a comment in virtual dom
|
||||
elem.attribs = _.omit elem.attribs, (val, attr) -> attr.indexOf('<') > -1 # Deku chokes on `<thing <p></p>`
|
||||
unless elem.name
|
||||
console.log("Failed to dekuify", elem)
|
||||
return elem.type
|
||||
deku.element(elem.name, elem.attribs, (@dekuify(c) for c in elem.children ? []))
|
||||
|
||||
extractStylesAndScripts: (dekuTree) ->
|
||||
#base case
|
||||
if dekuTree.type is '#text'
|
||||
return { virtualDom: dekuTree, styles: [], scripts: [] }
|
||||
if dekuTree.type is 'style'
|
||||
console.log 'Found a style: ', dekuTree
|
||||
return { styles: [dekuTree], scripts: [] }
|
||||
if dekuTree.type is 'script'
|
||||
console.log 'Found a script: ', dekuTree
|
||||
return { styles: [], scripts: [dekuTree] }
|
||||
# recurse over children
|
||||
childStyles = []
|
||||
childScripts = []
|
||||
dekuTree.children?.forEach (dekuChild, index) =>
|
||||
{ virtualDom, styles, scripts } = @extractStylesAndScripts(dekuChild)
|
||||
dekuTree.children[index] = virtualDom
|
||||
childStyles = childStyles.concat(styles)
|
||||
childScripts = childScripts.concat(scripts)
|
||||
dekuTree.children = _.filter dekuTree.children # Remove the nodes we extracted
|
||||
return { virtualDom: dekuTree, scripts: childScripts, styles: childStyles }
|
||||
|
||||
onIframeMessage: (event) =>
|
||||
origin = event.origin or event.originalEvent.origin
|
||||
|
|
Reference in a new issue