Skip to content

Instantly share code, notes, and snippets.

@FezVrasta
Last active December 26, 2015 03:46
Show Gist options
  • Save FezVrasta/0bfbf6e608abcf5b7ee1 to your computer and use it in GitHub Desktop.
Save FezVrasta/0bfbf6e608abcf5b7ee1 to your computer and use it in GitHub Desktop.
Wormhole for ember 1.6
{{#view SDC.WormholeView to="someElementId"}}
I'll be rendered somewhere
{{/view}}
<div id="someElementId"></div>
SDC.WormholeView = Ember.View.extend({
to: Ember.computed.alias('destinationElementId'),
destinationElementId: null,
destinationElement: Ember.computed('destinationElementId', 'renderInPlace', function() {
return this.get('renderInPlace') ? this.get('element') : document.getElementById(this.get('destinationElementId'));
}),
renderInPlace: false,
didInsertElement: function() {
this._super.call(this, arguments);
this._firstNode = this.get('element').firstChild;
this._lastNode = this.get('element').lastChild;
this.appendToDestination();
},
willDestroyElement: function() {
this._super.call(this, arguments);
var firstNode = this._firstNode;
var lastNode = this._lastNode;
Ember.run.schedule('render', () => {
this.removeRange(firstNode, lastNode);
});
},
destinationDidChange: Ember.observer('destinationElement', function() {
var destinationElement = this.get('destinationElement');
if (destinationElement !== this._firstNode.parentNode) {
Ember.run.schedule('render', this, 'appendToDestination');
}
}),
appendToDestination: function() {
var destinationElement = this.get('destinationElement');
var currentActiveElement = document.activeElement;
if (!destinationElement) {
var destinationElementId = this.get('destinationElementId');
if (destinationElementId) {
throw new Error(`ember-wormhole failed to render into '#${this.get('destinationElementId')}' because the element is not in the DOM`);
}
throw new Error('ember-wormhole failed to render content because the destinationElementId was set to an undefined or falsy value.');
}
this.appendRange(destinationElement, this._firstNode, this._lastNode);
if (document.activeElement !== currentActiveElement) {
currentActiveElement.focus();
}
},
appendRange: function(destinationElement, firstNode, lastNode) {
while(firstNode) {
destinationElement.insertBefore(firstNode, null);
firstNode = firstNode !== lastNode ? lastNode.parentNode.firstChild : null;
}
},
removeRange: function(firstNode, lastNode) {
var node = lastNode;
do {
var next = node.previousSibling;
if (node.parentNode) {
node.parentNode.removeChild(node);
if (node === firstNode) {
break;
}
}
node = next;
} while (node);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment