Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates CHANGELOG for v2.15.1 #336

Merged
merged 15 commits into from
Jan 12, 2018
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Software License Agreement (BSD License)

Copyright (c) 2017, Liferay Inc.
Copyright (c) 2018, Liferay Inc.
All rights reserved.

Redistribution and use of this software in source and binary forms, with or without modification, are
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Metal.js is a JavaScript library for building UI components in a solid, flexible
## Developer Tools for Metal.js
* [Chrome Extension](https://chrome.google.com/webstore/detail/metaljs-developer-tools/fagnjmppkokolnbloalifcmcooldhiik)

## Big Thanks

Cross-browser Testing Platform and Open Source <3 Provided by [Sauce Labs](https://saucelabs.com)

## License

[BSD License](https://github.com/metal/metal.js/blob/master/LICENSE.md) © Liferay, Inc.
45 changes: 45 additions & 0 deletions packages/metal-component/src/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ class Component extends EventEmitter {
*/
this.initialConfig_ = config || {};

/**
* Indicates whether the component should be rendered as a Portal, outside
* of the parent component.
* @type {string|Element|boolean}
*/
this.portalElement = null;

/**
* Whether the element was rendered.
* @type {boolean}
Expand All @@ -154,6 +161,8 @@ class Component extends EventEmitter {
this.setUpDataManager_();
this.setUpSyncUpdates_();

this.setUpPortal_(this.initialConfig_.portalElement);

this.on('stateWillChange', this.handleStateWillChange_);
this.on('stateChanged', this.handleComponentStateChanged_);
this.on('eventsChanged', this.onEventsChanged_);
Expand Down Expand Up @@ -658,6 +667,42 @@ class Component extends EventEmitter {
);
}

/**
* Overwrites element property if portalElement is passed. Creates
* a nested placeholder so that portalElement is not removed from the
* DOM when component first renders. When portalElement is equal to true,
* component is appeneded to the body.
*
* @param {string|Element|boolean} portalElement
*/
setUpPortal_(portalElement) {
if (
!isElement(portalElement) &&
!isString(portalElement) &&
!isBoolean(portalElement)
) {
return;
} else if (isBoolean(portalElement) && portalElement) {
portalElement = 'body';
}

if (isServerSide()) {
this.portalElement = true;
return;
}

portalElement = toElement(portalElement);

if (portalElement) {
const placeholder = document.createElement('div');

portalElement.appendChild(placeholder);

this.element = placeholder;
this.portalElement = portalElement;
}
}

/**
* Sets up the component's renderer.
* @protected
Expand Down
54 changes: 54 additions & 0 deletions packages/metal-component/test/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,60 @@ describe('Component', function() {
sinon.assert.calledWith(hookStub, comp);
});

it('should render component to portalElement', function() {
const portalElement = document.createElement('span');

comp = Component.render(Component, {
portalElement,
});

assert.strictEqual(comp.element.parentNode, portalElement);
assert.strictEqual(comp.portalElement, portalElement);
});

it('should set portalElement from selector', function() {
const portalElement = document.createElement('div');
portalElement.setAttribute('id', 'foo');

document.body.appendChild(portalElement);

comp = Component.render(Component, {
portalElement: '#foo',
});

assert.strictEqual(comp.element.parentNode, portalElement);
});

it('should set portalElement to body when set to true', function() {
const parentElement = document.createElement('span');

document.body.appendChild(parentElement);

comp = Component.render(
Component,
{
portalElement: true,
},
parentElement
);

assert.strictEqual(comp.element.parentNode, document.body);
});

it('should detach component from DOM when portalElement is passed', function() {
const portalElement = document.createElement('span');

comp = Component.render(Component, {
portalElement,
});

assert.ok(comp.inDocument);

comp.dispose();

assert.ok(!comp.inDocument);
});

function createCustomComponentClass(rendererContentOrFn) {
class CustomComponent extends Component {}
CustomComponent.RENDERER = createCustomRenderer(rendererContentOrFn);
Expand Down
4 changes: 3 additions & 1 deletion packages/metal-incremental-dom/src/IncrementalDomRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class IncrementalDomRenderer extends ComponentRenderer.constructor {
for (let i = 0; i < data.childComponents.length; i++) {
const child = data.childComponents[i];
if (!child.isDisposed()) {
child.element = null;
if (!child.portalElement) {
child.element = null;
}
child.dispose();
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/metal-incremental-dom/src/cleanup/unused.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export function disposeUnused() {
if (!comp.isDisposed() && !getData(comp).parent) {
// Don't let disposing cause the element to be removed, since it may
// be currently being reused by another component.
comp.element = null;
if (!comp.portalElement) {
comp.element = null;
}
comp.dispose();
}
}
Expand Down
10 changes: 9 additions & 1 deletion packages/metal-incremental-dom/src/render/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
isDef,
isDefAndNotNull,
isFunction,
isServerSide,
isString,
object,
} from 'metal';
Expand Down Expand Up @@ -537,7 +538,14 @@ function renderSubComponent_(tagOrCtor, config, owner) {
config.key = parentData.config.key;
}

comp.getRenderer().renderInsidePatch(comp);
if (comp.portalElement && isServerSide()) {
return comp;
}

if (!comp.portalElement) {
comp.getRenderer().renderInsidePatch(comp);
}

if (!comp.wasRendered) {
comp.renderComponent();
}
Expand Down
Loading