Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 120 additions & 13 deletions src/Elm/Kernel/VirtualDom.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,62 @@ function _VirtualDom_createTNode(domNode)
};
}

var _VirtualDom_init = F4(function(virtualNode, flagDecoder, debugMetadata, args)
var _VirtualDom_init = F3(function(virtualNode, flagDecoder, debugMetadata)
{
// NOTE: this function needs __Platform_export available to work

/**__PROD/
var node = args['node'];
//*/
var init = function(args)
{
/**__PROD/
var node = args['node'];
//*/
/**__DEBUG/
var node = args && args['node'] ? args['node'] : __Debug_crash(0);
//*/

var sendToApp = function() {};
var tNode = _VirtualDom_createTNode(undefined);
var nextNode = _VirtualDom_render(virtualNode, sendToApp, tNode);
nextNode.elmTree = tNode;
node.parentNode.replaceChild(nextNode, node);
node = nextNode;

var stopped = false;
var detachView = function()
{
// Make a second call to `app.detachView` do nothing.
if (stopped)
{
return node;
}
stopped = true;
_VirtualDom_removeAllEventListeners(node);
return node;
};

var app = {
detachView: detachView,
stop: detachView
};

/**__DEBUG/
app.hotReload = function(hotReloadData)
{
node = _VirtualDom_applyPatches(node, virtualNode, hotReloadData.__$virtualNode, sendToApp);
virtualNode = hotReloadData.__$virtualNode;
};
//*/

return app;
};

/**__DEBUG/
var node = args && args['node'] ? args['node'] : __Debug_crash(0);
init.hotReloadData = {
__$virtualNode: virtualNode
};
//*/

node.parentNode.replaceChild(
_VirtualDom_render(virtualNode, function() {}, _VirtualDom_createTNode(undefined)),
node
);

return {};
return init;
});


Expand Down Expand Up @@ -590,7 +629,9 @@ function _VirtualDom_render(vNode, eventNode, tNode)

if (_VirtualDom_divertHrefToApp && vNode.__tag == 'a')
{
domNode.addEventListener('click', _VirtualDom_divertHrefToApp(domNode));
var listener = _VirtualDom_divertHrefToApp(domNode);
domNode.elmAf = listener;
domNode.addEventListener('click', listener);
}

_VirtualDom_applyFacts(domNode, eventNode, {}, vNode.__facts);
Expand Down Expand Up @@ -1971,7 +2012,9 @@ function _VirtualDom_virtualizeHelp(node, tNode)

if (_VirtualDom_divertHrefToApp && node.localName === 'a')
{
node.addEventListener('click', _VirtualDom_divertHrefToApp(node));
var listener = _VirtualDom_divertHrefToApp(node);
node.elmAf = listener;
node.addEventListener('click', listener);
}
}

Expand Down Expand Up @@ -2054,3 +2097,67 @@ function _VirtualDom_dekey(keyedNode, tNode)
__descendantsCount: keyedNode.__descendantsCount
};
}

function _VirtualDom_removeAllEventListeners(rootDomNode)
{
var tNode = rootDomNode.elmTree;

// Allow mounting another Elm app on this DOM node.
delete rootDomNode.elmTree;

_VirtualDom_removeAllEventListenersHelp(tNode);
}

function _VirtualDom_removeAllEventListenersHelp(tNode)
{
var domNode = tNode.__domNode;
var children = tNode.__children;

// Allow the DOM nodes to be virtualized by another Elm app.
if (domNode.nodeType === 1)
{
domNode.setAttribute(_VirtualDom_markerProperty, '');
}

if (domNode.elmAf)
{
domNode.removeEventListener('click', domNode.elmAf);
delete domNode.elmAf;
}

var allCallbacks = domNode.elmFs;
if (allCallbacks)
{
for (var key in allCallbacks)
{
domNode.removeEventListener(key, allCallbacks[key]);
}
delete domNode.elmFs;
}

for (var key in children)
{
_VirtualDom_removeAllEventListenersHelp(children[key]);
}
}

// Used by `_Debugger_document` to remove the corner when shutting down.
function _VirtualDom_removeLastElmChild(rootDomNode)
{
var tNode = rootDomNode.elmTree;
var children = tNode.__children;
var childNodes = rootDomNode.childNodes;
for (var i = childNodes.length - 1; i >= 0; i--)
{
var childDomNode = childNodes[i];
for (var key in children)
{
if (childDomNode === children[key].__domNode)
{
rootDomNode.removeChild(childDomNode);
delete children[key];
return;
}
}
}
}