Skip to content

Commit

Permalink
wip #920
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-steele-idem committed Nov 9, 2017
1 parent 342a3e7 commit bc745f1
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 28 deletions.
10 changes: 8 additions & 2 deletions src/components/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var inherit = require('raptor-util/inherit');
var updateManager = require('./update-manager');
var morphdom = require('../morphdom');
var eventDelegation = require('./event-delegation');
var pairComponentNodes = require('./pairComponentNodes');

var slice = Array.prototype.slice;

Expand Down Expand Up @@ -451,7 +452,7 @@ Component.prototype = componentProto = {
}

var startNode = this.___startNode;
var endNodeNextSibling = this.___endNode.nextSibling;
var endNode = this.___endNode;

var doc = self.___document;
var input = this.___renderInput || this.___input;
Expand All @@ -466,6 +467,7 @@ Component.prototype = componentProto = {
var componentsContext = getComponentsContext(out);
var globalComponentsContext = componentsContext.___globalContext;
globalComponentsContext.___rerenderComponent = self;

globalComponentsContext.___isRerenderInBrowser = isRerenderInBrowser;

renderer(input, out);
Expand All @@ -474,10 +476,14 @@ Component.prototype = componentProto = {

var targetNode = out.___getOutput();

if (isRerenderInBrowser) {
pairComponentNodes(startNode, endNode, targetNode);
}

morphdom(
startNode.parentNode,
startNode,
endNodeNextSibling,
endNode.nextSibling,
targetNode,
doc,
componentsContext);
Expand Down
30 changes: 4 additions & 26 deletions src/components/init-components-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,34 +211,12 @@ function initServerRendered(renderedComponents, doc) {
} else if (flags & FLAG_HAS_HEAD_EL) {
startNode = endNode = document.head;
} else {
var startNodeComment = serverComponentStartNodes[componentId];
if (!startNodeComment) {
startNode = serverComponentStartNodes[componentId];
if (!startNode) {
indexServerComponentBoundaries(doc);
startNodeComment = serverComponentStartNodes[componentId];
}
var endNodeComment = serverComponentEndNodes[componentId];

startNode = startNodeComment.nextSibling;

if (startNode === endNodeComment) {
// Component has no output nodes so just mount to the start comment node
// and we will remove the end comment node
startNode = endNode = startNodeComment;
} else {
startNodeComment.parentNode.removeChild(startNodeComment);

if (startNode.parentNode === document) {
endNode = startNode = document.documentElement;
} else {
// Remove the start and end comment nodes and use the inner nodes
// as the boundary
endNode = endNodeComment.previousSibling;
}
}

if (endNodeComment) {
endNodeComment.parentNode.removeChild(endNodeComment);
startNode = serverComponentStartNodes[componentId];
}
endNode = serverComponentEndNodes[componentId];
}

component.___keyedElements = keyedElementsByComponentId[componentId] || {};
Expand Down
82 changes: 82 additions & 0 deletions src/components/pairComponentNodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
var ELEMENT_NODE = 1;
var TEXT_NODE = 3;
var COMMENT_NODE = 8;
var COMPONENT_NODE = 2;

function pairComponentNodes(startNode, endNode, vDocumentFragment) {
function pairComponentNodesHelper(realNode, vComponentNode) {
var component = vComponentNode.___component;
var commentPlaceholder;
var previousSibling;
var vComponentFirstChild = vComponentNode.___firstChild;

if (!vComponentFirstChild) {
// Target component does not have any children. We still need
// to assign it with a DOM node so we will create a placeholder
commentPlaceholder = document.createComment('$marko');
realNode.parentNode.insertBefore(commentPlaceholder, realNode);
component.___startNode = component.___endNode = commentPlaceholder;

// Continue pairing from the current DOM node that was already in
// the DOM:
return realNode;
}

var vFirstChildType = vComponentFirstChild.___nodeType;
if (vFirstChildType === COMPONENT_NODE) {
// The first child of this component is another component. We need
// our own DOM start node so we will have to create placeholder
// and use that
commentPlaceholder = document.createComment('$marko');
realNode.parentNode.insertBefore(commentPlaceholder, realNode);
component.___startNode = commentPlaceholder;

// Go ahead and pair the child component and we will continue
// pairing with the next DOM node after the component
previousSibling = pairComponentNodesHelper(realNode, vComponentFirstChild);
realNode = previousSibling.nextSibling;
} else {
previousSibling = component.___startNode = realNode;

realNode = realNode.nextSibling;
}


// We paired up the start node. Now we need to pair up the end nodes

var vCurrentNode = vComponentFirstChild.___nextSibling;
var vNextSibling;

while(vCurrentNode && realNode) {
var vNodeType = vCurrentNode.___nodeType;
vNextSibling = vCurrentNode.___nextSibling;

if (vNodeType === COMPONENT_NODE) {
previousSibling = pairComponentNodesHelper(realNode, vComponentFirstChild);
realNode = previousSibling.nextSibling;
} else {
if (vNextSibling) {
realNode = realNode.nextSibling;
} else {
// We reached the last vNode of the component and that means
// that the current real DOM node is the end node for this
// component
return (component.___endNode = realNode);
}
}

previousSibling = realNode;
vCurrentNode = vNextSibling;
}

commentPlaceholder = document.createComment('$marko');
realNode.parentNode.insertBefore(commentPlaceholder, previousSibling.nextSibling);
component.___endNode = commentPlaceholder;

return commentPlaceholder;
}

pairComponentNodesHelper(startNode.nextSibling, vDocumentFragment.___firstChild);
}

module.exports = pairComponentNodes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class {
}

<b model={}/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class {
}

<c/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class {
}

<d/>
<d/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class {
}

<div.d/>
7 changes: 7 additions & 0 deletions test/autotests/components-browser/nesting/index.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class {
}

<div.root>
<a />
</div>
5 changes: 5 additions & 0 deletions test/autotests/components-browser/nesting/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function(helpers) {
var component = helpers.mount(require('./index'), { });
component.forceUpdate();
component.update();
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class {
onMount() {
window.app = this;
}
}

<b model={} key="b"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class {
}

<c key="c"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class {
}

<d key="d1"/>
<d key="d2"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class {
}

<div.d/>
23 changes: 23 additions & 0 deletions test/autotests/components-pages/nesting/template.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
lasso-page dependencies=input.browserDependencies lasso=input.lasso

<!DOCTYPE html>
html lang="en"
head
meta charset="UTF-8"
title -- Marko Test
lasso-head
body

div id="test"
div id="mocha"
div id="testsTarget"

lasso-body

<a key="a"/>

init-components immediate

lasso-slot name="mocha-run"

browser-refresh
9 changes: 9 additions & 0 deletions test/autotests/components-pages/nesting/tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var path = require('path');

describe(path.basename(__dirname), function() {
it('should allow diffing html', function() {
var app = window.app;
app.forceUpdate();
app.update();
});
});

0 comments on commit bc745f1

Please sign in to comment.