From c0624f6e09c6d809f68935ef454062af8f48281c Mon Sep 17 00:00:00 2001 From: Diego Nascimento Date: Thu, 18 Jan 2018 14:21:22 -0300 Subject: [PATCH 1/2] Removing unecessary karma-mocha on plugins defition --- karma.conf.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 080fce0c..ba1346d5 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -35,13 +35,15 @@ module.exports = function(config) { // Since all files will be added, we need to ensure manually that these // will be added first. { - pattern: 'packages/metal-incremental-dom/src/incremental-dom.js', + pattern: + 'packages/metal-incremental-dom/src/incremental-dom.js', watched: false, included: true, served: true, }, { - pattern: 'packages/metal-incremental-dom/lib/incremental-dom.js', + pattern: + 'packages/metal-incremental-dom/lib/incremental-dom.js', watched: false, included: true, served: true, @@ -68,7 +70,8 @@ module.exports = function(config) { served: true, }, { - pattern: 'packages/metal-web-component/webcomponents_polyfill.js', + pattern: + 'packages/metal-web-component/webcomponents_polyfill.js', watched: false, included: true, served: true, @@ -87,21 +90,30 @@ module.exports = function(config) { }, ], - frameworks: ['browserify', 'mocha', 'chai', 'sinon', 'source-map-support'], + frameworks: [ + 'browserify', + 'mocha', + 'chai', + 'sinon', + 'source-map-support', + ], plugins: [ 'karma-browserify', 'karma-chai', 'karma-chrome-launcher', 'karma-mocha', - 'karma-mocha', 'karma-sinon', 'karma-source-map-support', ], preprocessors: { - 'packages/metal-incremental-dom/src/incremental-dom.js': ['browserify'], - 'packages/metal-incremental-dom/lib/incremental-dom.js': ['browserify'], + 'packages/metal-incremental-dom/src/incremental-dom.js': [ + 'browserify', + ], + 'packages/metal-incremental-dom/lib/incremental-dom.js': [ + 'browserify', + ], 'packages/metal-soy/node_modules/metal-soy-bundle/lib/bundle.js': [ 'browserify', ], From 722bdbaf2d675a15477c06803335e453c4e7a6bd Mon Sep 17 00:00:00 2001 From: Robert-Frampton Date: Thu, 18 Jan 2018 12:52:55 -0800 Subject: [PATCH 2/2] If a valid id is passed to portalElement and the element is not found, create an element with that id --- packages/metal-component/src/Component.js | 38 +++++++++++++++++++--- packages/metal-component/test/Component.js | 28 ++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/packages/metal-component/src/Component.js b/packages/metal-component/src/Component.js index 10a5a0ba..637e4179 100644 --- a/packages/metal-component/src/Component.js +++ b/packages/metal-component/src/Component.js @@ -12,7 +12,7 @@ import { object, } from 'metal'; import {syncState} from './sync/sync'; -import {DomEventEmitterProxy, toElement} from 'metal-dom'; +import {DomEventEmitterProxy, enterDocument, toElement} from 'metal-dom'; import ComponentDataManager from './ComponentDataManager'; import ComponentRenderer from './ComponentRenderer'; import {EventEmitter, EventHandler} from 'metal-events'; @@ -366,6 +366,33 @@ class Component extends EventEmitter { return this.initialConfig_; } + /** + * Gets portalElement based on selector. If an id is passed and the element + * does not exist, the element is created with that id and appended to the body. + * + * @param {string|Element} portalElementSelector + * @return {?Element} + */ + getPortalElement_(portalElementSelector) { + let portalElement = toElement(portalElementSelector); + + if (portalElement) { + return portalElement; + } + + if ( + portalElementSelector.indexOf('#') === 0 && + portalElementSelector.indexOf(' ') === -1 + ) { + portalElement = document.createElement('div'); + portalElement.setAttribute('id', portalElementSelector.slice(1)); + + enterDocument(portalElement); + } + + return portalElement; + } + /** * Gets state data for this component. * @return {!Object} @@ -677,9 +704,10 @@ class Component extends EventEmitter { */ setUpPortal_(portalElement) { if ( - !isElement(portalElement) && - !isString(portalElement) && - !isBoolean(portalElement) + !portalElement || + (!isElement(portalElement) && + !isString(portalElement) && + !isBoolean(portalElement)) ) { return; } else if (isBoolean(portalElement) && portalElement) { @@ -691,7 +719,7 @@ class Component extends EventEmitter { return; } - portalElement = toElement(portalElement); + portalElement = this.getPortalElement_(portalElement); if (portalElement) { const placeholder = document.createElement('div'); diff --git a/packages/metal-component/test/Component.js b/packages/metal-component/test/Component.js index 2f21c319..a1259fc0 100644 --- a/packages/metal-component/test/Component.js +++ b/packages/metal-component/test/Component.js @@ -1206,6 +1206,34 @@ describe('Component', function() { assert.ok(!comp.inDocument); }); + it('should create portal element if id is passed and element is not found', function() { + assert.ok(!document.getElementById('portal_test')); + + comp = Component.render(Component, { + portalElement: '#portal_test', + }); + + const portalElement = document.getElementById('portal_test'); + + assert.ok(portalElement); + assert.strictEqual(comp.element.parentNode, portalElement); + assert.strictEqual(comp.portalElement, portalElement); + }); + + it('should not create a portal element if a valid id is not passed', function() { + comp = Component.render(Component, { + portalElement: '#portal_test .class-selector', + }); + + assert.ok(!comp.portalElement); + + comp = Component.render(Component, { + portalElement: '.class-selector', + }); + + assert.ok(!comp.portalElement); + }); + function createCustomComponentClass(rendererContentOrFn) { class CustomComponent extends Component {} CustomComponent.RENDERER = createCustomRenderer(rendererContentOrFn);