-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Co-authored-by: Sergey Vinogradov <[email protected]>
- Loading branch information
1 parent
db354d9
commit 9222a72
Showing
42 changed files
with
314 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2021 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
*/ | ||
import { Constructor } from '@open-wc/dedupe-mixin'; | ||
import { ReactiveController, ReactiveControllerHost } from 'lit'; | ||
|
||
/** | ||
* A mixin for connecting controllers to the element. | ||
*/ | ||
export declare function ControllerMixin<T extends Constructor<HTMLElement>>( | ||
superclass: T | ||
): T & Constructor<ControllerMixinClass>; | ||
|
||
export declare class ControllerMixinClass | ||
implements Pick<ReactiveControllerHost, 'addController' | 'removeController'> | ||
{ | ||
/** | ||
* Registers a controller to participate in the element update cycle. | ||
*/ | ||
addController(controller: ReactiveController): void; | ||
|
||
/** | ||
* Removes a controller from the element. | ||
*/ | ||
removeController(controller: ReactiveController): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2021 Vaadin Ltd. | ||
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
*/ | ||
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js'; | ||
|
||
/** | ||
* A mixin for connecting controllers to the element. | ||
* | ||
* @polymerMixin | ||
*/ | ||
export const ControllerMixin = dedupingMixin( | ||
(superClass) => | ||
class ControllerMixinClass extends superClass { | ||
constructor() { | ||
super(); | ||
|
||
/** | ||
* @type {Set<import('lit').ReactiveController>} | ||
*/ | ||
this.__controllers = new Set(); | ||
} | ||
|
||
/** @protected */ | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
|
||
this.__controllers.forEach((c) => { | ||
c.hostConnected && c.hostConnected(); | ||
}); | ||
} | ||
|
||
/** @protected */ | ||
disconnectedCallback() { | ||
super.disconnectedCallback(); | ||
|
||
this.__controllers.forEach((c) => { | ||
c.hostDisconnected && c.hostDisconnected(); | ||
}); | ||
} | ||
|
||
/** | ||
* Registers a controller to participate in the element update cycle. | ||
* | ||
* @param {import('lit').ReactiveController} controller | ||
* @protected | ||
*/ | ||
addController(controller) { | ||
this.__controllers.add(controller); | ||
// Call hostConnected if a controller is added after the element is attached. | ||
if (this.$ !== undefined && this.isConnected && controller.hostConnected) { | ||
controller.hostConnected(); | ||
} | ||
} | ||
|
||
/** | ||
* Removes a controller from the element. | ||
* | ||
* @param {import('lit').ReactiveController} controller | ||
* @protected | ||
*/ | ||
removeController(controller) { | ||
this.__controllers.delete(controller); | ||
} | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { expect } from '@esm-bundle/chai'; | ||
import sinon from 'sinon'; | ||
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; | ||
import { ControllerMixin } from '../src/controller-mixin.js'; | ||
|
||
class ControllerHost extends ControllerMixin(PolymerElement) { | ||
static get is() { | ||
return 'controller-host'; | ||
} | ||
|
||
static get template() { | ||
return html`Content`; | ||
} | ||
} | ||
customElements.define(ControllerHost.is, ControllerHost); | ||
|
||
class SpyController { | ||
constructor(host) { | ||
this.host = host; | ||
} | ||
|
||
hostConnected() { | ||
// Used in spy | ||
} | ||
|
||
hostDisconnected() { | ||
// Used in spy | ||
} | ||
} | ||
|
||
describe('controller-mixin', () => { | ||
let element, controller; | ||
|
||
beforeEach(() => { | ||
element = document.createElement('controller-host'); | ||
controller = new SpyController(element); | ||
sinon.stub(controller, 'hostConnected'); | ||
sinon.stub(controller, 'hostDisconnected'); | ||
}); | ||
|
||
describe('hostConnected', () => { | ||
afterEach(() => { | ||
document.body.removeChild(element); | ||
}); | ||
|
||
it('should run hostConnected when controller is added before host is attached', () => { | ||
element.addController(controller); | ||
document.body.appendChild(element); | ||
expect(controller.hostConnected.calledOnce).to.be.true; | ||
}); | ||
|
||
it('should run hostConnected when controller is added after host is attached', () => { | ||
document.body.appendChild(element); | ||
element.addController(controller); | ||
expect(controller.hostConnected.calledOnce).to.be.true; | ||
}); | ||
}); | ||
|
||
describe('hostDisconnected', () => { | ||
beforeEach(() => { | ||
document.body.appendChild(element); | ||
element.addController(controller); | ||
}); | ||
|
||
it('should run hostDisconnected when host is detached', () => { | ||
document.body.removeChild(element); | ||
expect(controller.hostDisconnected.calledOnce).to.be.true; | ||
}); | ||
|
||
it('should not run hostDisconnected if controller is removed', () => { | ||
element.removeController(controller); | ||
document.body.removeChild(element); | ||
expect(controller.hostDisconnected.calledOnce).to.be.false; | ||
}); | ||
|
||
it('should run hostConnected when host is reattached', () => { | ||
document.body.removeChild(element); | ||
document.body.appendChild(element); | ||
expect(controller.hostConnected.calledTwice).to.be.true; | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.